Skip to content

Commit c3b43ac

Browse files
author
Nathan Kerr
committed
Merge branch 'master' of github.com:TheBosZ/dev_compiler
2 parents 1222de2 + 7bd37f0 commit c3b43ac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+6789
-4594
lines changed

pkg/dev_compiler/lib/runtime/dart_sdk.js

Lines changed: 3073 additions & 2379 deletions
Large diffs are not rendered by default.

pkg/dev_compiler/lib/src/compiler/code_generator.dart

Lines changed: 129 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ class CodeGenerator extends GeneralizingAstVisitor
119119

120120
String _buildRoot;
121121

122+
bool _superAllowed = true;
123+
124+
List<JS.TemporaryId> _superHelperSymbols = <JS.TemporaryId>[];
125+
List<JS.Method> _superHelpers = <JS.Method>[];
126+
122127
/// Whether we are currently generating code for the body of a `JS()` call.
123128
bool _isInForeignJS = false;
124129

@@ -596,6 +601,7 @@ class CodeGenerator extends GeneralizingAstVisitor
596601
var body = <JS.Statement>[];
597602
var extensions = _extensionsToImplement(classElem);
598603
_initExtensionSymbols(classElem, methods, fields, body);
604+
_emitSuperHelperSymbols(_superHelperSymbols, body);
599605

600606
// Emit the class, e.g. `core.Object = class Object { ... }`
601607
_defineClass(classElem, className, classExpr, body);
@@ -620,6 +626,14 @@ class CodeGenerator extends GeneralizingAstVisitor
620626
return _statement(body);
621627
}
622628

629+
void _emitSuperHelperSymbols(
630+
List<JS.TemporaryId> superHelperSymbols, List<JS.Statement> body) {
631+
for (var id in superHelperSymbols) {
632+
body.add(js.statement('const # = Symbol(#)', [id, js.string(id.name)]));
633+
}
634+
superHelperSymbols.clear();
635+
}
636+
623637
void _registerPropertyOverrides(
624638
ClassElement classElem,
625639
JS.Expression className,
@@ -898,6 +912,10 @@ class CodeGenerator extends GeneralizingAstVisitor
898912
jsMethods.add(_emitIterable(type));
899913
}
900914

915+
// Add all of the super helper methods
916+
jsMethods.addAll(_superHelpers);
917+
_superHelpers.clear();
918+
901919
return jsMethods.where((m) => m != null).toList(growable: false);
902920
}
903921

@@ -1631,7 +1649,7 @@ class CodeGenerator extends GeneralizingAstVisitor
16311649
}
16321650
}
16331651

1634-
JS.Method _emitMethodDeclaration(DartType type, MethodDeclaration node) {
1652+
JS.Method _emitMethodDeclaration(InterfaceType type, MethodDeclaration node) {
16351653
if (node.isAbstract) {
16361654
return null;
16371655
}
@@ -1957,8 +1975,11 @@ class CodeGenerator extends GeneralizingAstVisitor
19571975
} else {
19581976
_asyncStarController = null;
19591977
}
1978+
var savedSuperAllowed = _superAllowed;
1979+
_superAllowed = false;
19601980
// Visit the body with our async* controller set.
19611981
var jsBody = _visit(body);
1982+
_superAllowed = savedSuperAllowed;
19621983
_asyncStarController = savedController;
19631984

19641985
DartType returnType = _getExpectedReturnType(element);
@@ -2004,8 +2025,12 @@ class CodeGenerator extends GeneralizingAstVisitor
20042025
/// function instantiation.
20052026
@override
20062027
JS.Expression visitSimpleIdentifier(SimpleIdentifier node) {
2007-
return _applyFunctionTypeArguments(
2008-
_emitSimpleIdentifier(node), node.staticElement, node.staticType);
2028+
var typeArgs = _getTypeArgs(node.staticElement, node.staticType);
2029+
var simpleId = _emitSimpleIdentifier(node);
2030+
if (typeArgs == null) {
2031+
return simpleId;
2032+
}
2033+
return js.call('dart.gbind(#, #)', [simpleId, typeArgs]);
20092034
}
20102035

20112036
/// Emits a simple identifier, handling implicit `this` as well as
@@ -2385,17 +2410,66 @@ class CodeGenerator extends GeneralizingAstVisitor
23852410
return _emitMethodCall(target, node);
23862411
}
23872412

2388-
/// Emits a (possibly generic) instance method call.
23892413
JS.Expression _emitMethodCall(Expression target, MethodInvocation node) {
2414+
List<JS.Expression> args = _visit(node.argumentList);
2415+
var typeArgs = _emitInvokeTypeArguments(node);
2416+
2417+
if (target is SuperExpression && !_superAllowed) {
2418+
return _emitSuperHelperCall(typeArgs, args, target, node);
2419+
}
2420+
2421+
return _emitMethodCallInternal(target, node, args, typeArgs);
2422+
}
2423+
2424+
JS.Expression _emitSuperHelperCall(List<JS.Expression> typeArgs,
2425+
List<JS.Expression> args, SuperExpression target, MethodInvocation node) {
2426+
var fakeTypeArgs =
2427+
typeArgs?.map((_) => new JS.TemporaryId('a'))?.toList(growable: false);
2428+
var fakeArgs =
2429+
args.map((_) => new JS.TemporaryId('a')).toList(growable: false);
2430+
var combinedFakeArgs = <JS.TemporaryId>[];
2431+
if (fakeTypeArgs != null) {
2432+
combinedFakeArgs.addAll(fakeTypeArgs);
2433+
}
2434+
combinedFakeArgs.addAll(fakeArgs);
2435+
2436+
var forwardedCall =
2437+
_emitMethodCallInternal(target, node, fakeArgs, fakeTypeArgs);
2438+
var superForwarder = _getSuperHelperFor(
2439+
node.methodName.name, forwardedCall, combinedFakeArgs);
2440+
2441+
var combinedRealArgs = <JS.Expression>[];
2442+
if (typeArgs != null) {
2443+
combinedRealArgs.addAll(typeArgs);
2444+
}
2445+
combinedRealArgs.addAll(args);
2446+
2447+
return js.call('this.#(#)', [superForwarder, combinedRealArgs]);
2448+
}
2449+
2450+
JS.Expression _getSuperHelperFor(String name, JS.Expression forwardedCall,
2451+
List<JS.Expression> helperArgs) {
2452+
var helperMethod =
2453+
new JS.Fun(helperArgs, new JS.Block([new JS.Return(forwardedCall)]));
2454+
var helperMethodName = new JS.TemporaryId('super\$$name');
2455+
_superHelperSymbols.add(helperMethodName);
2456+
_superHelpers.add(new JS.Method(helperMethodName, helperMethod));
2457+
return helperMethodName;
2458+
}
2459+
2460+
/// Emits a (possibly generic) instance method call.
2461+
JS.Expression _emitMethodCallInternal(
2462+
Expression target,
2463+
MethodInvocation node,
2464+
List<JS.Expression> args,
2465+
List<JS.Expression> typeArgs) {
23902466
var type = getStaticType(target);
23912467
var name = node.methodName.name;
23922468
var element = node.methodName.staticElement;
23932469
bool isStatic = element is ExecutableElement && element.isStatic;
23942470
var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
23952471

23962472
JS.Expression jsTarget = _visit(target);
2397-
var typeArgs = _emitInvokeTypeArguments(node);
2398-
List<JS.Expression> args = _visit(node.argumentList);
23992473
if (DynamicInvoke.get(target)) {
24002474
if (typeArgs != null) {
24012475
return js.call('dart.dgsend(#, #, #, #)',
@@ -2411,6 +2485,7 @@ class CodeGenerator extends GeneralizingAstVisitor
24112485
}
24122486

24132487
jsTarget = new JS.PropertyAccess(jsTarget, memberName);
2488+
24142489
if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs);
24152490

24162491
if (DynamicInvoke.get(node.methodName)) {
@@ -3545,8 +3620,45 @@ class CodeGenerator extends GeneralizingAstVisitor
35453620
if (member is PropertyAccessorElement) {
35463621
member = (member as PropertyAccessorElement).variable;
35473622
}
3623+
String memberName = memberId.name;
3624+
var typeArgs = _getTypeArgs(member, resultType);
3625+
3626+
if (target is SuperExpression && !_superAllowed) {
3627+
return _emitSuperHelperAccess(target, member, memberName, typeArgs);
3628+
}
3629+
return _emitAccessInternal(target, member, memberName, typeArgs);
3630+
}
3631+
3632+
JS.Expression _emitSuperHelperAccess(SuperExpression target, Element member,
3633+
String memberName, List<JS.Expression> typeArgs) {
3634+
var fakeTypeArgs =
3635+
typeArgs?.map((_) => new JS.TemporaryId('a'))?.toList(growable: false);
3636+
3637+
var forwardedAccess =
3638+
_emitAccessInternal(target, member, memberName, fakeTypeArgs);
3639+
var superForwarder = _getSuperHelperFor(
3640+
memberName, forwardedAccess, fakeTypeArgs ?? const []);
3641+
3642+
return js.call('this.#(#)', [superForwarder, typeArgs ?? const []]);
3643+
}
3644+
3645+
List<JS.Expression> _getTypeArgs(Element member, DartType instantiated) {
3646+
DartType type;
3647+
if (member is ExecutableElement) {
3648+
type = member.type;
3649+
} else if (member is VariableElement) {
3650+
type = member.type;
3651+
}
3652+
3653+
// TODO(jmesserly): handle explicitly passed type args.
3654+
if (type == null) return null;
3655+
return _emitFunctionTypeArguments(type, instantiated);
3656+
}
3657+
3658+
JS.Expression _emitAccessInternal(Expression target, Element member,
3659+
String memberName, List<JS.Expression> typeArgs) {
35483660
bool isStatic = member is ClassMemberElement && member.isStatic;
3549-
var name = _emitMemberName(memberId.name,
3661+
var name = _emitMemberName(memberName,
35503662
type: getStaticType(target), isStatic: isStatic);
35513663
if (DynamicInvoke.get(target)) {
35523664
return js.call('dart.dload(#, #)', [_visit(target), name]);
@@ -3566,34 +3678,19 @@ class CodeGenerator extends GeneralizingAstVisitor
35663678
// Tear-off methods: explicitly bind it.
35673679
if (isSuper) {
35683680
result = js.call('dart.bind(this, #, #.#)', [name, jsTarget, name]);
3569-
} else if (_isObjectMemberCall(target, memberId.name)) {
3681+
} else if (_isObjectMemberCall(target, memberName)) {
35703682
result = js.call('dart.bind(#, #, dart.#)', [jsTarget, name, name]);
35713683
} else {
35723684
result = js.call('dart.bind(#, #)', [jsTarget, name]);
35733685
}
3574-
} else if (_isObjectMemberCall(target, memberId.name)) {
3686+
} else if (_isObjectMemberCall(target, memberName)) {
35753687
result = js.call('dart.#(#)', [name, jsTarget]);
35763688
} else {
35773689
result = js.call('#.#', [jsTarget, name]);
35783690
}
3579-
return _applyFunctionTypeArguments(result, member, resultType);
3580-
}
3581-
3582-
/// If this is an inferred instantiation of a generic function/method, this
3583-
/// will add the inferred type arguments.
3584-
JS.Expression _applyFunctionTypeArguments(
3585-
JS.Expression result, Element member, DartType instantiated) {
3586-
DartType type;
3587-
if (member is ExecutableElement) {
3588-
type = member.type;
3589-
} else if (member is VariableElement) {
3590-
type = member.type;
3691+
if (typeArgs == null) {
3692+
return result;
35913693
}
3592-
3593-
// TODO(jmesserly): handle explicitly passed type args.
3594-
if (type == null) return result;
3595-
var typeArgs = _emitFunctionTypeArguments(type, instantiated);
3596-
if (typeArgs == null) return result;
35973694
return js.call('dart.gbind(#, #)', [result, typeArgs]);
35983695
}
35993696

@@ -3791,8 +3888,12 @@ class CodeGenerator extends GeneralizingAstVisitor
37913888

37923889
@override
37933890
visitTryStatement(TryStatement node) {
3794-
return new JS.Try(_visit(node.body), _visitCatch(node.catchClauses),
3795-
_visit(node.finallyBlock));
3891+
var savedSuperAllowed = _superAllowed;
3892+
_superAllowed = false;
3893+
var finallyBlock = _visit(node.finallyBlock);
3894+
_superAllowed = savedSuperAllowed;
3895+
return new JS.Try(
3896+
_visit(node.body), _visitCatch(node.catchClauses), finallyBlock);
37963897
}
37973898

37983899
_visitCatch(NodeList<CatchClause> clauses) {

pkg/dev_compiler/lib/src/compiler/command.dart

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ class CompileCommand extends Command {
2424
CompileCommand({MessageHandler messageHandler})
2525
: this.messageHandler = messageHandler ?? print {
2626
argParser.addOption('out', abbr: 'o', help: 'Output file (required)');
27+
argParser.addOption('module-root',
28+
help: 'Root module directory. '
29+
'Generated module paths are relative to this root.');
2730
argParser.addOption('build-root',
28-
help: '''
29-
Root of source files. Generated library names are relative to this root.
30-
''');
31+
help: 'Root of source files. '
32+
'Generated library names are relative to this root.');
3133
CompilerOptions.addArguments(argParser);
3234
AnalyzerOptions.addArguments(argParser);
3335
}
@@ -50,8 +52,23 @@ Root of source files. Generated library names are relative to this root.
5052
} else {
5153
buildRoot = Directory.current.path;
5254
}
53-
var unit = new BuildUnit(path.basenameWithoutExtension(outPath), buildRoot,
54-
argResults.rest, _moduleForLibrary);
55+
var moduleRoot = argResults['module-root'] as String;
56+
String modulePath;
57+
if (moduleRoot != null) {
58+
moduleRoot = path.absolute(moduleRoot);
59+
if (!path.isWithin(moduleRoot, outPath)) {
60+
usageException('Output file $outPath must be within the module root '
61+
'directory $moduleRoot');
62+
}
63+
modulePath =
64+
path.withoutExtension(path.relative(outPath, from: moduleRoot));
65+
} else {
66+
moduleRoot = path.dirname(outPath);
67+
modulePath = path.basenameWithoutExtension(outPath);
68+
}
69+
70+
var unit = new BuildUnit(modulePath, buildRoot, argResults.rest,
71+
(source) => _moduleForLibrary(moduleRoot, source));
5572

5673
JSModuleFile module = compiler.compile(unit, compilerOptions);
5774
module.errors.forEach(messageHandler);
@@ -71,9 +88,17 @@ Root of source files. Generated library names are relative to this root.
7188
}
7289
}
7390

74-
String _moduleForLibrary(Source source) {
91+
String _moduleForLibrary(String moduleRoot, Source source) {
7592
if (source is InSummarySource) {
76-
return path.basenameWithoutExtension(source.summaryPath);
93+
var summaryPath = source.summaryPath;
94+
if (path.isWithin(moduleRoot, summaryPath)) {
95+
return path
96+
.withoutExtension(path.relative(summaryPath, from: moduleRoot));
97+
}
98+
99+
throw usageException(
100+
'Imported file ${source.uri} is not within the module root '
101+
'directory $moduleRoot');
77102
}
78103

79104
throw usageException(

pkg/dev_compiler/lib/src/compiler/source_map_printer.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2-
32
// for details. All rights reserved. Use of this source code is governed by a
43
// BSD-style license that can be found in the LICENSE file.
54

pkg/dev_compiler/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ author: Dart Dev Compiler team <[email protected]>
88
homepage: https://github.com/dart-lang/dev_compiler
99

1010
dependencies:
11-
analyzer: ^0.27.3
11+
analyzer: ^0.27.4-alpha.2
1212
args: ^0.13.0
1313
bazel_worker: ^0.1.0
1414
cli_util: ^0.0.1

0 commit comments

Comments
 (0)