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

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

Issue 1602203004: Serialize constant initializers. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add new summarize_const_expr.dart file. Created 4 years, 11 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
(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 library serialization.summarize_const_expr;
6
7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/scanner.dart';
9 import 'package:analyzer/src/summary/format.dart';
10
11 /**
12 * Instances of this class keep track of intermediate state during
13 * serialization of a single constant [Expression].
14 */
15 abstract class AbstractConstExprSerializer {
16 /**
17 * See [UnlinkedConstBuilder.operations].
18 */
19 final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[];
20
21 /**
22 * See [UnlinkedConstBuilder.ints].
23 */
24 final List<int> ints = <int>[];
25
26 /**
27 * See [UnlinkedConstBuilder.doubles].
28 */
29 final List<double> doubles = <double>[];
30
31 /**
32 * See [UnlinkedConstBuilder.strings].
33 */
34 final List<String> strings = <String>[];
35
36 /**
37 * See [UnlinkedConstBuilder.references].
38 */
39 final List<UnlinkedTypeRefBuilder> references = <UnlinkedTypeRefBuilder>[];
40
41 /**
42 * Serialize the given [expr] expression into this serializer state.
43 */
44 void serialize(Expression expr) {
45 if (expr is IntegerLiteral) {
46 _pushInt(expr.value);
47 } else if (expr is DoubleLiteral) {
48 operations.add(UnlinkedConstOperation.pushDouble);
49 doubles.add(expr.value);
50 } else if (expr is BooleanLiteral) {
51 if (expr.value) {
52 operations.add(UnlinkedConstOperation.pushTrue);
53 } else {
54 operations.add(UnlinkedConstOperation.pushFalse);
55 }
56 } else if (expr is StringLiteral) {
57 _serializeString(expr);
58 } else if (expr is SymbolLiteral) {
59 strings.add(expr.components.map((token) => token.lexeme).join('.'));
60 operations.add(UnlinkedConstOperation.pushString);
61 operations.add(UnlinkedConstOperation.makeSymbol);
62 } else if (expr is NullLiteral) {
63 operations.add(UnlinkedConstOperation.pushNull);
64 } else if (expr is Identifier) {
65 references.add(serializeIdentifier(expr));
66 } else if (expr is InstanceCreationExpression) {
67 _serializeInstanceCreation(expr);
68 } else if (expr is ListLiteral) {
69 _serializeListLiteral(expr);
70 } else if (expr is MapLiteral) {
71 _serializeMapLiteral(expr);
72 } else if (expr is MethodInvocation) {
73 String name = expr.methodName.name;
74 if (name != 'identical') {
75 throw new _ConstExprSerializationError(
76 'Only "identity" function invocation is allowed.');
77 }
78 if (expr.argumentList == null ||
79 expr.argumentList.arguments.length != 2) {
80 throw new _ConstExprSerializationError(
81 'The function "identity" requires exactly 2 arguments.');
82 }
83 expr.argumentList.arguments.forEach(serialize);
84 operations.add(UnlinkedConstOperation.identical);
85 } else if (expr is BinaryExpression) {
86 _serializeBinaryExpression(expr);
87 } else if (expr is ConditionalExpression) {
88 serialize(expr.condition);
89 serialize(expr.thenExpression);
90 serialize(expr.elseExpression);
91 operations.add(UnlinkedConstOperation.conditional);
92 } else if (expr is PrefixExpression) {
93 _serializePrefixExpression(expr);
94 } else if (expr is PropertyAccess && expr.propertyName.name == 'length') {
95 serialize(expr.target);
96 operations.add(UnlinkedConstOperation.length);
97 } else if (expr is ParenthesizedExpression) {
98 serialize(expr.expression);
99 } else {
100 throw new _ConstExprSerializationError('Unknown expression type: $expr');
101 }
102 }
103
104 /**
105 * Return [UnlinkedTypeRefBuilder] that corresponds to the given [identifier].
106 */
107 UnlinkedTypeRefBuilder serializeIdentifier(Identifier identifier);
108
109 /**
110 * Return [UnlinkedTypeRefBuilder] that corresponds to the given [type].
111 */
112 UnlinkedTypeRefBuilder serializeType(TypeName type);
113
114 /**
115 * Return the [UnlinkedConstBuilder] that corresponds to the state of this
116 * serializer.
117 */
118 UnlinkedConstBuilder toBuilder() {
119 return new UnlinkedConstBuilder(
120 operations: operations,
121 ints: ints,
122 doubles: doubles,
123 strings: strings,
124 references: references);
125 }
126
127 void _pushInt(int value) {
128 // TODO(scheglov) add support for arbitrary precision ints
129 assert(value.abs() < (2 << 31));
130 ints.add(value & 0xFFFFFFFF);
131 operations.add(UnlinkedConstOperation.pushInt);
132 }
133
134 void _serializeBinaryExpression(BinaryExpression expr) {
135 serialize(expr.leftOperand);
136 serialize(expr.rightOperand);
137 TokenType operator = expr.operator.type;
138 if (operator == TokenType.EQ_EQ) {
139 operations.add(UnlinkedConstOperation.equal);
140 } else if (operator == TokenType.BANG_EQ) {
141 operations.add(UnlinkedConstOperation.equal);
142 operations.add(UnlinkedConstOperation.not);
143 } else if (operator == TokenType.AMPERSAND_AMPERSAND) {
144 operations.add(UnlinkedConstOperation.and);
145 } else if (operator == TokenType.BAR_BAR) {
146 operations.add(UnlinkedConstOperation.or);
147 } else if (operator == TokenType.CARET) {
148 operations.add(UnlinkedConstOperation.bitXor);
149 } else if (operator == TokenType.AMPERSAND) {
150 operations.add(UnlinkedConstOperation.bitAnd);
151 } else if (operator == TokenType.BAR) {
152 operations.add(UnlinkedConstOperation.bitOr);
153 } else if (operator == TokenType.GT_GT) {
154 operations.add(UnlinkedConstOperation.bitShiftRight);
155 } else if (operator == TokenType.LT_LT) {
156 operations.add(UnlinkedConstOperation.bitShiftLeft);
157 } else if (operator == TokenType.PLUS) {
158 operations.add(UnlinkedConstOperation.add);
159 } else if (operator == TokenType.MINUS) {
160 operations.add(UnlinkedConstOperation.subtract);
161 } else if (operator == TokenType.STAR) {
162 operations.add(UnlinkedConstOperation.multiply);
163 } else if (operator == TokenType.SLASH) {
164 operations.add(UnlinkedConstOperation.divide);
165 } else if (operator == TokenType.TILDE_SLASH) {
166 operations.add(UnlinkedConstOperation.floorDivide);
167 } else if (operator == TokenType.GT) {
168 operations.add(UnlinkedConstOperation.greater);
169 } else if (operator == TokenType.LT) {
170 operations.add(UnlinkedConstOperation.less);
171 } else if (operator == TokenType.GT_EQ) {
172 operations.add(UnlinkedConstOperation.greaterEqual);
173 } else if (operator == TokenType.LT_EQ) {
174 operations.add(UnlinkedConstOperation.lessEqual);
175 } else if (operator == TokenType.PERCENT) {
176 operations.add(UnlinkedConstOperation.modulo);
177 } else {
178 throw new _ConstExprSerializationError('Unknown operator: $operator');
179 }
180 }
181
182 void _serializeInstanceCreation(InstanceCreationExpression expr) {
183 ConstructorName constructor = expr.constructorName;
184 List<Expression> arguments = expr.argumentList.arguments;
185 arguments.forEach(serialize);
186 operations.add(UnlinkedConstOperation.invokeConstructor);
187 references.add(serializeType(constructor.type));
188 if (constructor.name != null) {
189 strings.add(constructor.name.name);
190 } else {
191 strings.add('');
192 }
193 // TODO(scheglov) named arguments?
194 ints.add(arguments.length);
195 }
196
197 void _serializeListLiteral(ListLiteral expr) {
198 List<Expression> elements = expr.elements;
199 elements.forEach(serialize);
200 TypeName typeArgument;
201 if (expr.typeArguments != null &&
202 expr.typeArguments.arguments.length == 1) {
203 typeArgument = expr.typeArguments.arguments[0];
204 }
205 references.add(serializeType(typeArgument));
206 ints.add(elements.length);
207 operations.add(UnlinkedConstOperation.makeList);
208 }
209
210 void _serializeMapLiteral(MapLiteral expr) {
211 for (MapLiteralEntry entry in expr.entries) {
212 serialize(entry.key);
213 serialize(entry.value);
214 }
215 TypeName keyTypeArgument;
216 TypeName valueTypeArgument;
217 if (expr.typeArguments != null &&
218 expr.typeArguments.arguments.length == 2) {
219 keyTypeArgument = expr.typeArguments.arguments[0];
220 valueTypeArgument = expr.typeArguments.arguments[1];
221 }
222 references.add(serializeType(keyTypeArgument));
223 references.add(serializeType(valueTypeArgument));
224 ints.add(expr.entries.length);
225 operations.add(UnlinkedConstOperation.makeMap);
226 }
227
228 void _serializePrefixExpression(PrefixExpression expr) {
229 serialize(expr.operand);
230 TokenType operator = expr.operator.type;
231 if (operator == TokenType.BANG) {
232 operations.add(UnlinkedConstOperation.not);
233 } else if (operator == TokenType.MINUS) {
234 operations.add(UnlinkedConstOperation.negate);
235 } else if (operator == TokenType.TILDE) {
236 operations.add(UnlinkedConstOperation.complement);
237 } else {
238 throw new _ConstExprSerializationError('Unknown operator: $operator');
239 }
240 }
241
242 void _serializeString(StringLiteral expr) {
243 if (expr is AdjacentStrings) {
244 if (expr.strings.every((string) => string is SimpleStringLiteral)) {
245 operations.add(UnlinkedConstOperation.pushString);
246 strings.add(expr.stringValue);
247 } else {
248 expr.strings.forEach(_serializeString);
249 operations.add(UnlinkedConstOperation.concatenate);
250 ints.add(expr.strings.length);
251 }
252 } else if (expr is SimpleStringLiteral) {
253 operations.add(UnlinkedConstOperation.pushString);
254 strings.add(expr.value);
255 } else {
256 StringInterpolation interpolation = expr as StringInterpolation;
257 for (InterpolationElement element in interpolation.elements) {
258 if (element is InterpolationString) {
259 operations.add(UnlinkedConstOperation.pushString);
260 strings.add(element.value);
261 } else {
262 serialize((element as InterpolationExpression).expression);
263 }
264 }
265 operations.add(UnlinkedConstOperation.concatenate);
266 ints.add(interpolation.elements.length);
267 }
268 }
269 }
270
271 /**
272 * Error that describes a problem during a constant expression serialization.
273 */
274 class _ConstExprSerializationError {
275 final String message;
276
277 _ConstExprSerializationError(this.message);
278
279 @override
280 String toString() => message;
281 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698