Skip to content

Commit

Permalink
fix #543, export of properties should now work
Browse files Browse the repository at this point in the history
top-level fields, getters, setters were all broken

R=vsm@google.com

Review URL: https://codereview.chromium.org/1949733002 .
  • Loading branch information
John Messerly committed May 3, 2016
1 parent 44db042 commit 2b20f3d
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 119 deletions.
50 changes: 32 additions & 18 deletions pkg/dev_compiler/lib/runtime/dart_sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -1183,10 +1183,18 @@ dart_library.library('dart_sdk', null, /* Imports */[
}
return true;
};
dart.defineProperty = Object.defineProperty;
dart.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
dart.getOwnPropertyNames = Object.getOwnPropertyNames;
dart.getOwnPropertySymbols = Object.getOwnPropertySymbols;
dart.defineProperty = function(obj, name, desc) {
return Object.defineProperty(obj, name, desc);
};
dart.getOwnPropertyDescriptor = function(obj, name) {
return Object.getOwnPropertyDescriptor(obj, name);
};
dart.getOwnPropertyNames = function(obj) {
return Object.getOwnPropertyNames(obj);
};
dart.getOwnPropertySymbols = function(obj) {
return Object.getOwnPropertySymbols(obj);
};
dart.hasOwnProperty = Object.prototype.hasOwnProperty;
dart.StrongModeError = (function() {
function StrongModeError(message) {
Expand All @@ -1204,11 +1212,13 @@ dart_library.library('dart_sdk', null, /* Imports */[
throw Error(message);
};
dart.getOwnNamesAndSymbols = function(obj) {
return dart.getOwnPropertyNames(obj).concat(dart.getOwnPropertySymbols(obj));
let names = dart.getOwnPropertyNames(obj);
let symbols = dart.getOwnPropertySymbols(obj);
return names.concat(symbols);
};
dart.safeGetOwnProperty = function(obj, name) {
let desc = dart.getOwnPropertyDescriptor(obj, name);
if (desc) return desc.value;
if (desc != null) return desc.value;
};
dart.defineLazyProperty = function(to, name, desc) {
let init = desc.get;
Expand Down Expand Up @@ -1242,21 +1252,25 @@ dart_library.library('dart_sdk', null, /* Imports */[
};
dart.copyTheseProperties = function(to, from, names) {
for (let name of names) {
let desc = dart.getOwnPropertyDescriptor(from, name);
if (desc != void 0) {
if (name == Symbol.iterator) {
let existing = dart.getOwnPropertyDescriptor(to, name);
if (existing != null) {
if (existing.writable) to[Symbol.iterator] = desc.value;
continue;
}
dart.copyProperty(to, from, name);
}
return to;
};
dart.copyProperty = function(to, from, name) {
let desc = dart.getOwnPropertyDescriptor(from, name);
if (name == Symbol.iterator) {
let existing = dart.getOwnPropertyDescriptor(to, name);
if (existing != null) {
if (existing.writable) {
to[name] = desc.value;
}
dart.defineProperty(to, name, desc);
} else {
dart.defineLazyProperty(to, name, () => from[name]);
return;
}
}
return to;
dart.defineProperty(to, name, desc);
};
dart.export = function(to, from, name) {
return dart.copyProperty(to, from, name);
};
dart.copyProperties = function(to, from) {
return dart.copyTheseProperties(to, from, dart.getOwnNamesAndSymbols(from));
Expand Down
29 changes: 27 additions & 2 deletions pkg/dev_compiler/lib/src/compiler/code_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class CodeGenerator extends GeneralizingAstVisitor

final _hasDeferredSupertype = new HashSet<ClassElement>();

final _eagerTopLevelFields = new HashSet<Element>.identity();

/// The type provider from the current Analysis [context].
final TypeProvider types;

Expand Down Expand Up @@ -382,15 +384,34 @@ class CodeGenerator extends GeneralizingAstVisitor
var exportedNames =
new NamespaceBuilder().createExportNamespaceForDirective(element);

var libraryName = emitLibraryName(currentLibrary);

// TODO(jmesserly): we could collect all of the names for bulk re-export,
// but this is easier to implement for now.
void emitExport(Element export, {String suffix: ''}) {
var name = _emitTopLevelName(export, suffix: suffix);
_moduleItems.add(js.statement(
'#.# = #;', [emitLibraryName(currentLibrary), name.selector, name]));

if (export is TypeDefiningElement || export is FunctionElement ||
_eagerTopLevelFields.contains(export)) {
// classes, typedefs, functions, and eager init fields can be assigned
// directly.
// TODO(jmesserly): we don't know about eager init fields from other
// modules we import, so we will never go down this code path for them.
_moduleItems
.add(js.statement('#.# = #;', [libraryName, name.selector, name]));
} else {
// top-level fields, getters, setters need to copy the property
// descriptor.
_moduleItems.add(js.statement('dart.export(#, #, #);',
[libraryName, name.receiver, name.selector]));
}
}

for (var export in exportedNames.definedNames.values) {
if (export is PropertyAccessorElement) {
export = (export as PropertyAccessorElement).variable;
}

// Don't allow redefining names from this library.
if (currentNames.containsKey(export.name)) continue;

Expand Down Expand Up @@ -2795,6 +2816,10 @@ class CodeGenerator extends GeneralizingAstVisitor
// TODO(jmesserly): we don't track dependencies correctly for these.
var isJSTopLevel = field.isFinal && _isFinalJSDecl(field);
if (eagerInit || isJSTopLevel) {
// Remember that we emitted it this way, so re-export can take advantage
// of this fact.
_eagerTopLevelFields.add(element);

return annotate(
js.statement('# = #;', [_emitTopLevelName(element), jsInit]),
field,
Expand Down
58 changes: 29 additions & 29 deletions pkg/dev_compiler/test/codegen/expect/unittest.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,75 +185,75 @@ dart_library.library('unittest', null, /* Imports */[
if (isLayoutTest === void 0) isLayoutTest = false;
};
dart.fn(unittest.useHtmlConfiguration, dart.void, [], [core.bool]);
unittest.isPositive = src__numeric_matchers.isPositive;
unittest.isRangeError = src__error_matchers.isRangeError;
unittest.isStateError = src__error_matchers.isStateError;
dart.export(unittest, src__numeric_matchers, 'isPositive');
dart.export(unittest, src__error_matchers, 'isRangeError');
dart.export(unittest, src__error_matchers, 'isStateError');
unittest.equals = src__core_matchers.equals;
unittest.CustomMatcher = src__core_matchers.CustomMatcher;
unittest.inOpenClosedRange = src__numeric_matchers.inOpenClosedRange;
unittest.pairwiseCompare = src__iterable_matchers.pairwiseCompare;
unittest.equalsIgnoringCase = src__string_matchers.equalsIgnoringCase;
unittest.isUnimplementedError = src__error_matchers.isUnimplementedError;
dart.export(unittest, src__error_matchers, 'isUnimplementedError');
unittest.hasLength = src__core_matchers.hasLength;
unittest.StringDescription = src__description.StringDescription;
unittest.allOf = src__operator_matchers.allOf;
unittest.isNegative = src__numeric_matchers.isNegative;
dart.export(unittest, src__numeric_matchers, 'isNegative');
unittest.isInstanceOf$ = src__core_matchers.isInstanceOf$;
unittest.isInstanceOf = src__core_matchers.isInstanceOf;
unittest.isNaN = src__core_matchers.isNaN;
dart.export(unittest, src__core_matchers, 'isNaN');
unittest.lessThan = src__numeric_matchers.lessThan;
unittest.isNotEmpty = src__core_matchers.isNotEmpty;
dart.export(unittest, src__core_matchers, 'isNotEmpty');
unittest.greaterThanOrEqualTo = src__numeric_matchers.greaterThanOrEqualTo;
unittest.endsWith = src__string_matchers.endsWith;
unittest.isConcurrentModificationError = src__error_matchers.isConcurrentModificationError;
dart.export(unittest, src__error_matchers, 'isConcurrentModificationError');
unittest.containsValue = src__map_matchers.containsValue;
unittest.isFalse = src__core_matchers.isFalse;
unittest.isTrue = src__core_matchers.isTrue;
dart.export(unittest, src__core_matchers, 'isFalse');
dart.export(unittest, src__core_matchers, 'isTrue');
unittest.Matcher = src__interfaces.Matcher;
unittest.lessThanOrEqualTo = src__numeric_matchers.lessThanOrEqualTo;
unittest.matches = src__string_matchers.matches;
unittest.returnsNormally = src__core_matchers.returnsNormally;
dart.export(unittest, src__core_matchers, 'returnsNormally');
unittest.TypeMatcher = src__core_matchers.TypeMatcher;
unittest.inExclusiveRange = src__numeric_matchers.inExclusiveRange;
unittest.equalsIgnoringWhitespace = src__string_matchers.equalsIgnoringWhitespace;
unittest.isIn = src__core_matchers.isIn;
unittest.isNotNaN = src__core_matchers.isNotNaN;
unittest.isNonZero = src__numeric_matchers.isNonZero;
dart.export(unittest, src__core_matchers, 'isNotNaN');
dart.export(unittest, src__numeric_matchers, 'isNonZero');
unittest.startsWith = src__string_matchers.startsWith;
unittest.isNullThrownError = src__error_matchers.isNullThrownError;
unittest.isEmpty = src__core_matchers.isEmpty;
dart.export(unittest, src__error_matchers, 'isNullThrownError');
dart.export(unittest, src__core_matchers, 'isEmpty');
unittest.anyOf = src__operator_matchers.anyOf;
unittest.unorderedMatches = src__iterable_matchers.unorderedMatches;
unittest.isZero = src__numeric_matchers.isZero;
unittest.isList = src__core_matchers.isList;
dart.export(unittest, src__numeric_matchers, 'isZero');
dart.export(unittest, src__core_matchers, 'isList');
unittest.escape = src__util.escape;
unittest.isCyclicInitializationError = src__error_matchers.isCyclicInitializationError;
dart.export(unittest, src__error_matchers, 'isCyclicInitializationError');
unittest.anyElement = src__iterable_matchers.anyElement;
unittest.anything = src__core_matchers.anything;
dart.export(unittest, src__core_matchers, 'anything');
unittest.contains = src__core_matchers.contains;
unittest.isUnsupportedError = src__error_matchers.isUnsupportedError;
unittest.isNonPositive = src__numeric_matchers.isNonPositive;
dart.export(unittest, src__error_matchers, 'isUnsupportedError');
dart.export(unittest, src__numeric_matchers, 'isNonPositive');
unittest.isNot = src__operator_matchers.isNot;
unittest.same = src__core_matchers.same;
unittest.inClosedOpenRange = src__numeric_matchers.inClosedOpenRange;
unittest.predicate = src__core_matchers.predicate;
unittest.isNotNull = src__core_matchers.isNotNull;
dart.export(unittest, src__core_matchers, 'isNotNull');
unittest.wrapMatcher = src__util.wrapMatcher;
unittest.isNoSuchMethodError = src__error_matchers.isNoSuchMethodError;
dart.export(unittest, src__error_matchers, 'isNoSuchMethodError');
unittest.unorderedEquals = src__iterable_matchers.unorderedEquals;
unittest.everyElement = src__iterable_matchers.everyElement;
unittest.addStateInfo = src__util.addStateInfo;
unittest.isArgumentError = src__error_matchers.isArgumentError;
unittest.isException = src__error_matchers.isException;
dart.export(unittest, src__error_matchers, 'isArgumentError');
dart.export(unittest, src__error_matchers, 'isException');
unittest.inInclusiveRange = src__numeric_matchers.inInclusiveRange;
unittest.containsPair = src__map_matchers.containsPair;
unittest.isFormatException = src__error_matchers.isFormatException;
dart.export(unittest, src__error_matchers, 'isFormatException');
unittest.orderedEquals = src__iterable_matchers.orderedEquals;
unittest.collapseWhitespace = src__string_matchers.collapseWhitespace;
unittest.greaterThan = src__numeric_matchers.greaterThan;
unittest.isNonNegative = src__numeric_matchers.isNonNegative;
unittest.isNull = src__core_matchers.isNull;
unittest.isMap = src__core_matchers.isMap;
dart.export(unittest, src__numeric_matchers, 'isNonNegative');
dart.export(unittest, src__core_matchers, 'isNull');
dart.export(unittest, src__core_matchers, 'isMap');
unittest.stringContainsInOrder = src__string_matchers.stringContainsInOrder;
unittest.closeTo = src__numeric_matchers.closeTo;
unittest.Description = src__interfaces.Description;
Expand Down
58 changes: 29 additions & 29 deletions pkg/dev_compiler/test/codegen/expect/unittest/unittest.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,75 +185,75 @@ dart_library.library('unittest', null, /* Imports */[
if (isLayoutTest === void 0) isLayoutTest = false;
};
dart.fn(unittest.useHtmlConfiguration, dart.void, [], [core.bool]);
unittest.isPositive = src__numeric_matchers.isPositive;
unittest.isRangeError = src__error_matchers.isRangeError;
unittest.isStateError = src__error_matchers.isStateError;
dart.export(unittest, src__numeric_matchers, 'isPositive');
dart.export(unittest, src__error_matchers, 'isRangeError');
dart.export(unittest, src__error_matchers, 'isStateError');
unittest.equals = src__core_matchers.equals;
unittest.CustomMatcher = src__core_matchers.CustomMatcher;
unittest.inOpenClosedRange = src__numeric_matchers.inOpenClosedRange;
unittest.pairwiseCompare = src__iterable_matchers.pairwiseCompare;
unittest.equalsIgnoringCase = src__string_matchers.equalsIgnoringCase;
unittest.isUnimplementedError = src__error_matchers.isUnimplementedError;
dart.export(unittest, src__error_matchers, 'isUnimplementedError');
unittest.hasLength = src__core_matchers.hasLength;
unittest.StringDescription = src__description.StringDescription;
unittest.allOf = src__operator_matchers.allOf;
unittest.isNegative = src__numeric_matchers.isNegative;
dart.export(unittest, src__numeric_matchers, 'isNegative');
unittest.isInstanceOf$ = src__core_matchers.isInstanceOf$;
unittest.isInstanceOf = src__core_matchers.isInstanceOf;
unittest.isNaN = src__core_matchers.isNaN;
dart.export(unittest, src__core_matchers, 'isNaN');
unittest.lessThan = src__numeric_matchers.lessThan;
unittest.isNotEmpty = src__core_matchers.isNotEmpty;
dart.export(unittest, src__core_matchers, 'isNotEmpty');
unittest.greaterThanOrEqualTo = src__numeric_matchers.greaterThanOrEqualTo;
unittest.endsWith = src__string_matchers.endsWith;
unittest.isConcurrentModificationError = src__error_matchers.isConcurrentModificationError;
dart.export(unittest, src__error_matchers, 'isConcurrentModificationError');
unittest.containsValue = src__map_matchers.containsValue;
unittest.isFalse = src__core_matchers.isFalse;
unittest.isTrue = src__core_matchers.isTrue;
dart.export(unittest, src__core_matchers, 'isFalse');
dart.export(unittest, src__core_matchers, 'isTrue');
unittest.Matcher = src__interfaces.Matcher;
unittest.lessThanOrEqualTo = src__numeric_matchers.lessThanOrEqualTo;
unittest.matches = src__string_matchers.matches;
unittest.returnsNormally = src__core_matchers.returnsNormally;
dart.export(unittest, src__core_matchers, 'returnsNormally');
unittest.TypeMatcher = src__core_matchers.TypeMatcher;
unittest.inExclusiveRange = src__numeric_matchers.inExclusiveRange;
unittest.equalsIgnoringWhitespace = src__string_matchers.equalsIgnoringWhitespace;
unittest.isIn = src__core_matchers.isIn;
unittest.isNotNaN = src__core_matchers.isNotNaN;
unittest.isNonZero = src__numeric_matchers.isNonZero;
dart.export(unittest, src__core_matchers, 'isNotNaN');
dart.export(unittest, src__numeric_matchers, 'isNonZero');
unittest.startsWith = src__string_matchers.startsWith;
unittest.isNullThrownError = src__error_matchers.isNullThrownError;
unittest.isEmpty = src__core_matchers.isEmpty;
dart.export(unittest, src__error_matchers, 'isNullThrownError');
dart.export(unittest, src__core_matchers, 'isEmpty');
unittest.anyOf = src__operator_matchers.anyOf;
unittest.unorderedMatches = src__iterable_matchers.unorderedMatches;
unittest.isZero = src__numeric_matchers.isZero;
unittest.isList = src__core_matchers.isList;
dart.export(unittest, src__numeric_matchers, 'isZero');
dart.export(unittest, src__core_matchers, 'isList');
unittest.escape = src__util.escape;
unittest.isCyclicInitializationError = src__error_matchers.isCyclicInitializationError;
dart.export(unittest, src__error_matchers, 'isCyclicInitializationError');
unittest.anyElement = src__iterable_matchers.anyElement;
unittest.anything = src__core_matchers.anything;
dart.export(unittest, src__core_matchers, 'anything');
unittest.contains = src__core_matchers.contains;
unittest.isUnsupportedError = src__error_matchers.isUnsupportedError;
unittest.isNonPositive = src__numeric_matchers.isNonPositive;
dart.export(unittest, src__error_matchers, 'isUnsupportedError');
dart.export(unittest, src__numeric_matchers, 'isNonPositive');
unittest.isNot = src__operator_matchers.isNot;
unittest.same = src__core_matchers.same;
unittest.inClosedOpenRange = src__numeric_matchers.inClosedOpenRange;
unittest.predicate = src__core_matchers.predicate;
unittest.isNotNull = src__core_matchers.isNotNull;
dart.export(unittest, src__core_matchers, 'isNotNull');
unittest.wrapMatcher = src__util.wrapMatcher;
unittest.isNoSuchMethodError = src__error_matchers.isNoSuchMethodError;
dart.export(unittest, src__error_matchers, 'isNoSuchMethodError');
unittest.unorderedEquals = src__iterable_matchers.unorderedEquals;
unittest.everyElement = src__iterable_matchers.everyElement;
unittest.addStateInfo = src__util.addStateInfo;
unittest.isArgumentError = src__error_matchers.isArgumentError;
unittest.isException = src__error_matchers.isException;
dart.export(unittest, src__error_matchers, 'isArgumentError');
dart.export(unittest, src__error_matchers, 'isException');
unittest.inInclusiveRange = src__numeric_matchers.inInclusiveRange;
unittest.containsPair = src__map_matchers.containsPair;
unittest.isFormatException = src__error_matchers.isFormatException;
dart.export(unittest, src__error_matchers, 'isFormatException');
unittest.orderedEquals = src__iterable_matchers.orderedEquals;
unittest.collapseWhitespace = src__string_matchers.collapseWhitespace;
unittest.greaterThan = src__numeric_matchers.greaterThan;
unittest.isNonNegative = src__numeric_matchers.isNonNegative;
unittest.isNull = src__core_matchers.isNull;
unittest.isMap = src__core_matchers.isMap;
dart.export(unittest, src__numeric_matchers, 'isNonNegative');
dart.export(unittest, src__core_matchers, 'isNull');
dart.export(unittest, src__core_matchers, 'isMap');
unittest.stringContainsInOrder = src__string_matchers.stringContainsInOrder;
unittest.closeTo = src__numeric_matchers.closeTo;
unittest.Description = src__interfaces.Description;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) 2016, 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.

export 'export_order_test.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) 2016, 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.

import 'export_order_helper1.dart';

class Info {
int x = y;
}
15 changes: 15 additions & 0 deletions pkg/dev_compiler/test/codegen/language/export_order_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2016, 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.

import 'package:expect/expect.dart';
import 'export_order_helper1.dart' as bar;
import 'export_order_helper2.dart';

final y = 38;
final info = new Info();

void main() {
Expect.equals(38, info.x);
Expect.equals(38, bar.y);
}
Loading

0 comments on commit 2b20f3d

Please sign in to comment.