Index: lib/compiler/implementation/js_backend/constant_emitter.dart |
diff --git a/lib/compiler/implementation/js_backend/constant_emitter.dart b/lib/compiler/implementation/js_backend/constant_emitter.dart |
deleted file mode 100644 |
index 0deca511506e520c03f7f7743bb3ea8d083cbf20..0000000000000000000000000000000000000000 |
--- a/lib/compiler/implementation/js_backend/constant_emitter.dart |
+++ /dev/null |
@@ -1,252 +0,0 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-class ConstantEmitter implements ConstantVisitor { |
- final Compiler compiler; |
- final Namer namer; |
- |
- CodeBuffer buffer; |
- bool shouldEmitCanonicalVersion; |
- |
- ConstantEmitter(this.compiler, this.namer); |
- |
- /** |
- * Unless the constant can be emitted multiple times (as for numbers and |
- * strings) use the canonical name. |
- */ |
- void emitCanonicalVersionOfConstant(Constant constant, CodeBuffer newBuffer) { |
- shouldEmitCanonicalVersion = true; |
- buffer = newBuffer; |
- _visit(constant); |
- } |
- |
- /** |
- * Emit the JavaScript code of the constant. If the constant must be |
- * canonicalized this method emits the initialization value. |
- */ |
- void emitJavaScriptCodeForConstant(Constant constant, CodeBuffer newBuffer) { |
- shouldEmitCanonicalVersion = false; |
- buffer = newBuffer; |
- _visit(constant); |
- } |
- |
- _visit(Constant constant) { |
- constant.accept(this); |
- } |
- |
- void visitSentinel(SentinelConstant constant) { |
- if (shouldEmitCanonicalVersion) { |
- buffer.add(namer.CURRENT_ISOLATE); |
- } else { |
- compiler.internalError( |
- "The parameter sentinel constant does not need specific JS code"); |
- } |
- } |
- |
- void visitFunction(FunctionConstant constant) { |
- if (shouldEmitCanonicalVersion) { |
- buffer.add(namer.isolatePropertiesAccess(constant.element)); |
- } else { |
- compiler.internalError( |
- "The function constant does not need specific JS code"); |
- } |
- } |
- |
- void visitNull(NullConstant constant) { |
- buffer.add("null"); |
- } |
- |
- void visitInt(IntConstant constant) { |
- buffer.add(constant.value.toString()); |
- } |
- |
- void visitDouble(DoubleConstant constant) { |
- double value = constant.value; |
- if (value.isNaN()) { |
- buffer.add("(0/0)"); |
- } else if (value == double.INFINITY) { |
- buffer.add("(1/0)"); |
- } else if (value == -double.INFINITY) { |
- buffer.add("(-1/0)"); |
- } else { |
- buffer.add("$value"); |
- } |
- } |
- |
- void visitTrue(TrueConstant constant) { |
- buffer.add("true"); |
- } |
- |
- void visitFalse(FalseConstant constant) { |
- buffer.add("false"); |
- } |
- |
- /** |
- * Write the contents of the quoted string to a [CodeBuffer] in |
- * a form that is valid as JavaScript string literal content. |
- * The string is assumed quoted by single quote characters. |
- */ |
- void writeEscapedString(DartString string, |
- CodeBuffer buffer, |
- Node diagnosticNode) { |
- Iterator<int> iterator = string.iterator(); |
- while (iterator.hasNext()) { |
- int code = iterator.next(); |
- if (code === $SQ) { |
- buffer.add(@"\'"); |
- } else if (code === $LF) { |
- buffer.add(@'\n'); |
- } else if (code === $CR) { |
- buffer.add(@'\r'); |
- } else if (code === $LS) { |
- // This Unicode line terminator and $PS are invalid in JS string |
- // literals. |
- buffer.add(@'\u2028'); |
- } else if (code === $PS) { |
- buffer.add(@'\u2029'); |
- } else if (code === $BACKSLASH) { |
- buffer.add(@'\\'); |
- } else { |
- if (code > 0xffff) { |
- compiler.reportError( |
- diagnosticNode, |
- 'Unhandled non-BMP character: U+${code.toRadixString(16)}'); |
- } |
- // TODO(lrn): Consider whether all codes above 0x7f really need to |
- // be escaped. We build a Dart string here, so it should be a literal |
- // stage that converts it to, e.g., UTF-8 for a JS interpreter. |
- if (code < 0x20) { |
- buffer.add(@'\x'); |
- if (code < 0x10) buffer.add('0'); |
- buffer.add(code.toRadixString(16)); |
- } else if (code >= 0x80) { |
- if (code < 0x100) { |
- buffer.add(@'\x'); |
- } else { |
- buffer.add(@'\u'); |
- if (code < 0x1000) { |
- buffer.add('0'); |
- } |
- } |
- buffer.add(code.toRadixString(16)); |
- } else { |
- buffer.addCharCode(code); |
- } |
- } |
- } |
- } |
- |
- void visitString(StringConstant constant) { |
- buffer.add("'"); |
- writeEscapedString(constant.value, buffer, constant.node); |
- buffer.add("'"); |
- } |
- |
- void emitCanonicalVersion(Constant constant) { |
- String name = namer.constantName(constant); |
- buffer.add(namer.isolatePropertiesAccessForConstant(name)); |
- } |
- |
- void visitList(ListConstant constant) { |
- if (shouldEmitCanonicalVersion) { |
- emitCanonicalVersion(constant); |
- } else { |
- shouldEmitCanonicalVersion = true; |
- buffer.add("${namer.ISOLATE}.makeConstantList"); |
- buffer.add("(["); |
- for (int i = 0; i < constant.entries.length; i++) { |
- if (i != 0) buffer.add(", "); |
- _visit(constant.entries[i]); |
- } |
- buffer.add("])"); |
- } |
- } |
- |
- String getJsConstructor(ClassElement element) { |
- return namer.isolatePropertiesAccess(element); |
- } |
- |
- void visitMap(MapConstant constant) { |
- if (shouldEmitCanonicalVersion) { |
- emitCanonicalVersion(constant); |
- } else { |
- void writeJsMap() { |
- buffer.add("{"); |
- int valueIndex = 0; |
- for (int i = 0; i < constant.keys.entries.length; i++) { |
- StringConstant key = constant.keys.entries[i]; |
- if (key.value == MapConstant.PROTO_PROPERTY) continue; |
- |
- if (valueIndex != 0) buffer.add(", "); |
- |
- // Keys in literal maps must be emitted in place. |
- emitJavaScriptCodeForConstant(key, buffer); |
- |
- buffer.add(": "); |
- emitCanonicalVersionOfConstant(constant.values[valueIndex++], buffer); |
- } |
- buffer.add("}"); |
- if (valueIndex != constant.values.length) { |
- compiler.internalError("Bad value count."); |
- } |
- } |
- |
- void badFieldCountError() { |
- compiler.internalError( |
- "Compiler and ConstantMap disagree on number of fields."); |
- } |
- |
- shouldEmitCanonicalVersion = true; |
- |
- ClassElement classElement = constant.type.element; |
- buffer.add("new "); |
- buffer.add(getJsConstructor(classElement)); |
- buffer.add("("); |
- // The arguments of the JavaScript constructor for any given Dart class |
- // are in the same order as the members of the class element. |
- int emittedArgumentCount = 0; |
- classElement.forEachInstanceField( |
- includeBackendMembers: true, |
- includeSuperMembers: true, |
- f: (ClassElement enclosing, Element field) { |
- if (emittedArgumentCount != 0) buffer.add(", "); |
- if (field.name == MapConstant.LENGTH_NAME) { |
- buffer.add(constant.keys.entries.length); |
- } else if (field.name == MapConstant.JS_OBJECT_NAME) { |
- writeJsMap(); |
- } else if (field.name == MapConstant.KEYS_NAME) { |
- emitCanonicalVersionOfConstant(constant.keys, buffer); |
- } else if (field.name == MapConstant.PROTO_VALUE) { |
- assert(constant.protoValue !== null); |
- emitCanonicalVersionOfConstant(constant.protoValue, buffer); |
- } else { |
- badFieldCountError(); |
- } |
- emittedArgumentCount++; |
- }); |
- if ((constant.protoValue === null && emittedArgumentCount != 3) || |
- (constant.protoValue !== null && emittedArgumentCount != 4)) { |
- badFieldCountError(); |
- } |
- buffer.add(")"); |
- } |
- } |
- |
- void visitConstructed(ConstructedConstant constant) { |
- if (shouldEmitCanonicalVersion) { |
- emitCanonicalVersion(constant); |
- } else { |
- shouldEmitCanonicalVersion = true; |
- |
- buffer.add("new "); |
- buffer.add(getJsConstructor(constant.type.element)); |
- buffer.add("("); |
- for (int i = 0; i < constant.fields.length; i++) { |
- if (i != 0) buffer.add(", "); |
- _visit(constant.fields[i]); |
- } |
- buffer.add(")"); |
- } |
- } |
-} |