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

Unified Diff: dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 19405002: Implement reflecting on static fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 829d6b8d19b153715c3ddef8671064b35fdcff11..82049b43d053c080f39f0f6c59eeb4faeadfd260 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -82,6 +82,7 @@ class CodeEmitterTask extends CompilerTask {
final List<ClassElement> nativeClasses = <ClassElement>[];
final List<Selector> trivialNsmHandlers = <Selector>[];
final Map<String, String> mangledFieldNames = <String, String>{};
+ final Map<String, String> mangledGlobalFieldNames = <String, String>{};
final Set<String> recordedMangledNames = new Set<String>();
final Set<String> interceptorInvocationNames = new Set<String>();
@@ -1457,6 +1458,7 @@ class CodeEmitterTask extends CompilerTask {
* Invariant: [classElement] must be a declaration element.
*/
void visitClassFields(ClassElement classElement,
+ bool visitStatics,
void addField(Element member,
String name,
String accessorName,
@@ -1523,18 +1525,22 @@ class CodeEmitterTask extends CompilerTask {
}
}
- // TODO(kasperl): We should make sure to only emit one version of
- // overridden fields. Right now, we rely on the ordering so the
- // fields pulled in from mixins are replaced with the fields from
- // the class definition.
+ if (visitStatics) {
+ classElement.implementation.forEachStaticField(visitField);
+ } else {
+ // TODO(kasperl): We should make sure to only emit one version of
+ // overridden fields. Right now, we rely on the ordering so the
+ // fields pulled in from mixins are replaced with the fields from
+ // the class definition.
- // If a class is not instantiated then we add the field just so we can
- // generate the field getter/setter dynamically. Since this is only
- // allowed on fields that are in [classElement] we don't need to visit
- // superclasses for non-instantiated classes.
- classElement.implementation.forEachInstanceField(
- visitField,
- includeSuperAndInjectedMembers: isInstantiated);
+ // If a class is not instantiated then we add the field just so we can
+ // generate the field getter/setter dynamically. Since this is only
+ // allowed on fields that are in [classElement] we don't need to visit
+ // superclasses for non-instantiated classes.
+ classElement.implementation.forEachInstanceField(
+ visitField,
+ includeSuperAndInjectedMembers: isInstantiated);
+ }
}
void generateGetter(Element member, String fieldName, String accessorName,
@@ -1620,9 +1626,16 @@ class CodeEmitterTask extends CompilerTask {
String accessorName,
String memberName) {
if (!backend.retainGetter(member)) return;
- String previousName = mangledFieldNames.putIfAbsent(
- '${namer.getterPrefix}$accessorName',
- () => memberName);
+ String previousName;
+ if (member.isInstanceMember()) {
+ previousName = mangledFieldNames.putIfAbsent(
+ '${namer.getterPrefix}$accessorName',
+ () => memberName);
+ } else {
+ previousName = mangledGlobalFieldNames.putIfAbsent(
+ accessorName,
+ () => memberName);
+ }
assert(invariant(member, previousName == memberName,
message: '$previousName != ${memberName}'));
}
@@ -1631,26 +1644,30 @@ class CodeEmitterTask extends CompilerTask {
bool emitClassFields(ClassElement classElement,
ClassBuilder builder,
String superName,
- { bool classIsNative: false }) {
+ { bool classIsNative: false,
+ bool emitStatics: false }) {
assert(superName != null);
String separator = '';
String nativeName = namer.getPrimitiveInterceptorRuntimeName(classElement);
StringBuffer buffer = new StringBuffer();
- if (nativeName != null) {
- buffer.write('$nativeName/');
+ if (!emitStatics) {
+ if (nativeName != null) {
+ buffer.write('$nativeName/');
+ }
+ buffer.write('$superName;');
}
- buffer.write('$superName;');
int bufferClassLength = buffer.length;
var fieldMetadata = [];
bool hasMetadata = false;
- visitClassFields(classElement, (Element member,
- String name,
- String accessorName,
- bool needsGetter,
- bool needsSetter,
- bool needsCheckedSetter) {
+ visitClassFields(classElement, emitStatics,
+ (Element member,
+ String name,
+ String accessorName,
+ bool needsGetter,
+ bool needsSetter,
+ bool needsCheckedSetter) {
// Ignore needsCheckedSetter - that is handled below.
bool needsAccessor = (needsGetter || needsSetter);
// We need to output the fields for non-native classes so we can auto-
@@ -1728,12 +1745,13 @@ class CodeEmitterTask extends CompilerTask {
void emitClassGettersSetters(ClassElement classElement,
ClassBuilder builder) {
- visitClassFields(classElement, (Element member,
- String name,
- String accessorName,
- bool needsGetter,
- bool needsSetter,
- bool needsCheckedSetter) {
+ visitClassFields(classElement, false,
+ (Element member,
+ String name,
+ String accessorName,
+ bool needsGetter,
+ bool needsSetter,
+ bool needsCheckedSetter) {
compiler.withCurrentElement(member, () {
if (needsCheckedSetter) {
assert(!needsSetter);
@@ -1793,20 +1811,31 @@ class CodeEmitterTask extends CompilerTask {
emitIsTests(classElement, builder);
List<CodeBuffer> classBuffers = elementBuffers[classElement];
- CodeBuffer statics = new CodeBuffer();
- bool hasStatics = false;
- if (classBuffers != null) {
- statics.write('{$n');
+ if (classBuffers == null) {
+ classBuffers = [];
+ } else {
elementBuffers.remove(classElement);
- for (CodeBuffer classBuffer in classBuffers) {
- // TODO(ahe): What about deferred?
- if (classBuffer != null) {
- hasStatics = true;
- statics.addBuffer(classBuffer);
- }
- }
- statics.write('}$n');
}
+ CodeBuffer statics = new CodeBuffer();
+ statics.write('{$n');
+ bool hasStatics = false;
+ ClassBuilder staticsBuilder = new ClassBuilder();
+ if (emitClassFields(
+ classElement, staticsBuilder, superName, emitStatics: true)) {
+ hasStatics = true;
+ statics.write('"":$_');
+ statics.write(
+ jsAst.prettyPrint(staticsBuilder.properties.single.value, compiler));
+ statics.write(',$n');
+ }
+ for (CodeBuffer classBuffer in classBuffers) {
+ // TODO(ahe): What about deferred?
+ if (classBuffer != null) {
+ hasStatics = true;
+ statics.addBuffer(classBuffer);
+ }
+ }
+ statics.write('}$n');
if (hasStatics) {
builder.addProperty('static', new jsAst.Blob(statics));
}
@@ -3494,6 +3523,22 @@ if (typeof document !== "undefined" && document.readyState !== "complete") {
mainBuffer.write(';');
}
}
+ if (!mangledGlobalFieldNames.isEmpty) {
+ var keys = mangledGlobalFieldNames.keys.toList();
+ keys.sort();
+ var properties = [];
+ for (String key in keys) {
+ var value = js.string('${mangledGlobalFieldNames[key]}');
+ properties.add(new jsAst.Property(js.string(key), value));
+ }
+ var map = new jsAst.ObjectInitializer(properties);
+ mainBuffer.write(
+ jsAst.prettyPrint(
+ js('init.mangledGlobalNames = #', map).toStatement(), compiler));
ngeoffray 2013/07/17 07:41:11 long line
ahe 2013/07/17 08:39:15 Done.
+ if (compiler.enableMinification) {
+ mainBuffer.write(';');
+ }
+ }
mainBuffer
..write(getReflectionDataParser())
..write('([$n');
@@ -3761,6 +3806,7 @@ if (typeof document !== "undefined" && document.readyState !== "complete") {
function processStatics(descriptor) {
for (var property in descriptor) {
if (!hasOwnProperty.call(descriptor, property)) continue;
+ if (property === "") continue;
var element = descriptor[property];
var firstChar = property.substring(0, 1);
var previousProperty;

Powered by Google App Engine
This is Rietveld 408576698