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

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

Issue 11572009: Support for typedef in checked mode. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of js_backend; 5 part of js_backend;
6 6
7 /** 7 /**
8 * A function element that represents a closure call. The signature is copied 8 * A function element that represents a closure call. The signature is copied
9 * from the given element. 9 * from the given element.
10 */ 10 */
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 new js.VariableUse('receiver') 1105 new js.VariableUse('receiver')
1106 .dot(name) 1106 .dot(name)
1107 .callWith(arguments))])); 1107 .callWith(arguments))]));
1108 1108
1109 CodeBuffer code = new CodeBuffer(); 1109 CodeBuffer code = new CodeBuffer();
1110 code.add(js.prettyPrint(function, compiler)); 1110 code.add(js.prettyPrint(function, compiler));
1111 defineInstanceMember(name, code); 1111 defineInstanceMember(name, code);
1112 } 1112 }
1113 } 1113 }
1114 1114
1115 void emitTypedefChecksOn(DartType type, void emitTest(Element element)) {
1116 for (TypedefElement typedef in checkedTypedefs) {
1117 FunctionType typedefType =
1118 typedef.computeType(compiler).unalias(compiler);
1119 if (compiler.types.isSubtype(type, typedefType)) {
1120 emitTest(typedef);
1121 }
1122 }
1123 }
1124
1115 /** 1125 /**
1116 * Generate "is tests" for [cls]: itself, and the "is tests" for the 1126 * Generate "is tests" for [cls]: itself, and the "is tests" for the
1117 * classes it implements. We don't need to add the "is tests" of the 1127 * classes it implements. We don't need to add the "is tests" of the
1118 * super class because they will be inherited at runtime. 1128 * super class because they will be inherited at runtime.
1119 */ 1129 */
1120 void generateIsTestsOn(ClassElement cls, 1130 void generateIsTestsOn(ClassElement cls,
1121 void emitIsTest(Element element)) { 1131 void emitIsTest(Element element)) {
1122 if (checkedClasses.contains(cls)) { 1132 if (checkedClasses.contains(cls)) {
1123 emitIsTest(cls); 1133 emitIsTest(cls);
1124 } 1134 }
1125 1135
1126 Set<Element> generated = new Set<Element>(); 1136 Set<Element> generated = new Set<Element>();
1127 // A class that defines a [:call:] method implicitly implements 1137 // A class that defines a [:call:] method implicitly implements
1128 // [Function] and needs checks for all typedefs that are used in is-checks. 1138 // [Function] and needs checks for all typedefs that are used in is-checks.
1129 if (checkedClasses.contains(compiler.functionClass) || 1139 if (checkedClasses.contains(compiler.functionClass) ||
1130 !checkedTypedefs.isEmpty) { 1140 !checkedTypedefs.isEmpty) {
1131 FunctionElement call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME); 1141 FunctionElement call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
1132 if (call == null) { 1142 if (call == null) {
1133 // If [cls] is a closure, it has a synthetic call operator method. 1143 // If [cls] is a closure, it has a synthetic call operator method.
1134 call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME); 1144 call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
1135 } 1145 }
1136 if (call != null) { 1146 if (call != null) {
1137 generateInterfacesIsTests(compiler.functionClass, 1147 generateInterfacesIsTests(compiler.functionClass,
1138 emitIsTest, 1148 emitIsTest,
1139 generated); 1149 generated);
1140 FunctionType callType = call.computeType(compiler); 1150 emitTypedefChecksOn(call.computeType(compiler), emitIsTest);
1141 for (TypedefElement typedef in checkedTypedefs) {
1142 FunctionType typedefType =
1143 typedef.computeType(compiler).unalias(compiler);
1144 if (compiler.types.isSubtype(callType, typedefType)) {
1145 emitIsTest(typedef);
1146 }
1147 }
1148 } 1151 }
1149 } 1152 }
1150 for (DartType interfaceType in cls.interfaces) { 1153 for (DartType interfaceType in cls.interfaces) {
1151 generateInterfacesIsTests(interfaceType.element, emitIsTest, generated); 1154 generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
1152 } 1155 }
1153 } 1156 }
1154 1157
1155 /** 1158 /**
1156 * Generate "is tests" where [cls] is being implemented. 1159 * Generate "is tests" where [cls] is being implemented.
1157 */ 1160 */
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 1278
1276 void emitStaticFunctionWithNamer(CodeBuffer buffer, 1279 void emitStaticFunctionWithNamer(CodeBuffer buffer,
1277 Element element, 1280 Element element,
1278 CodeBuffer functionBuffer, 1281 CodeBuffer functionBuffer,
1279 String functionNamer(Element element)) { 1282 String functionNamer(Element element)) {
1280 String functionName = functionNamer(element); 1283 String functionName = functionNamer(element);
1281 buffer.add('$isolateProperties.$functionName$_=$_'); 1284 buffer.add('$isolateProperties.$functionName$_=$_');
1282 buffer.add(functionBuffer); 1285 buffer.add(functionBuffer);
1283 buffer.add('$N$n'); 1286 buffer.add('$N$n');
1284 } 1287 }
1288
1285 void emitStaticFunctionsWithNamer(CodeBuffer buffer, 1289 void emitStaticFunctionsWithNamer(CodeBuffer buffer,
1286 Map<Element, CodeBuffer> generatedCode, 1290 Map<Element, CodeBuffer> generatedCode,
1287 String functionNamer(Element element)) { 1291 String functionNamer(Element element)) {
1288 generatedCode.forEach((Element element, CodeBuffer functionBuffer) { 1292 generatedCode.forEach((Element element, CodeBuffer functionBuffer) {
1289 if (!element.isInstanceMember() && !element.isField()) { 1293 if (!element.isInstanceMember() && !element.isField()) {
1290 emitStaticFunctionWithNamer( 1294 emitStaticFunctionWithNamer(
1291 buffer, element, functionBuffer,functionNamer); 1295 buffer, element, functionBuffer,functionNamer);
1292 } 1296 }
1293 }); 1297 });
1294 } 1298 }
(...skipping 22 matching lines...) Expand all
1317 String invocationName = namer.instanceMethodName(callElement); 1321 String invocationName = namer.instanceMethodName(callElement);
1318 String fieldAccess = '$isolateProperties.$staticName'; 1322 String fieldAccess = '$isolateProperties.$staticName';
1319 buffer.add("$fieldAccess.$invocationName$_=$_$fieldAccess$N"); 1323 buffer.add("$fieldAccess.$invocationName$_=$_$fieldAccess$N");
1320 addParameterStubs(callElement, (String name, CodeBuffer value) { 1324 addParameterStubs(callElement, (String name, CodeBuffer value) {
1321 buffer.add('$fieldAccess.$name$_=$_$value$N'); 1325 buffer.add('$fieldAccess.$name$_=$_$value$N');
1322 }); 1326 });
1323 // If a static function is used as a closure we need to add its name 1327 // If a static function is used as a closure we need to add its name
1324 // in case it is used in spawnFunction. 1328 // in case it is used in spawnFunction.
1325 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; 1329 String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
1326 buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N'); 1330 buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N');
1331 emitTypedefChecksOn(element.computeType(compiler), (Element typedef) {
1332 String operator = namer.operatorIs(typedef);
1333 buffer.add('$fieldAccess.$operator$_=${_}true$N');
1334 });
1327 } 1335 }
1328 } 1336 }
1329 1337
1330 void emitBoundClosureClassHeader(String mangledName, 1338 void emitBoundClosureClassHeader(String mangledName,
1331 String superName, 1339 String superName,
1332 List<String> fieldNames, 1340 List<String> fieldNames,
1333 CodeBuffer buffer) { 1341 CodeBuffer buffer) {
1334 buffer.add('$classesCollector.$mangledName$_=$_' 1342 buffer.add('$classesCollector.$mangledName$_=$_'
1335 '{"":"$superName;${Strings.join(fieldNames,',')}",'); 1343 '{"":"$superName;${Strings.join(fieldNames,',')}",');
1336 } 1344 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 new js.This().dot(fieldNames[0]), 1438 new js.This().dot(fieldNames[0]),
1431 new js.This().dot(fieldNames[1])) 1439 new js.This().dot(fieldNames[1]))
1432 .callWith(arguments))])); 1440 .callWith(arguments))]));
1433 1441
1434 boundClosureBuffer.add( 1442 boundClosureBuffer.add(
1435 '$_$invocationName:$_${js.prettyPrint(fun,compiler)}'); 1443 '$_$invocationName:$_${js.prettyPrint(fun,compiler)}');
1436 1444
1437 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) { 1445 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) {
1438 boundClosureBuffer.add(',\n$_$stubName:$_$memberValue'); 1446 boundClosureBuffer.add(',\n$_$stubName:$_$memberValue');
1439 }); 1447 });
1448
1449 emitTypedefChecksOn(member.computeType(compiler), (Element typedef) {
1450 String operator = namer.operatorIs(typedef);
1451 boundClosureBuffer.add(',\n$_$operator$_:${_}true');
1452 });
1453
1440 boundClosureBuffer.add("$n}$N"); 1454 boundClosureBuffer.add("$n}$N");
1441 1455
1442 closureClass = namer.isolateAccess(closureClassElement); 1456 closureClass = namer.isolateAccess(closureClassElement);
1443 1457
1444 // Cache it. 1458 // Cache it.
1445 if (!hasOptionalParameters) { 1459 if (!hasOptionalParameters) {
1446 cache[parameterCount] = closureClass; 1460 cache[parameterCount] = closureClass;
1447 } 1461 }
1448 } 1462 }
1449 1463
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 """; 2081 """;
2068 const String HOOKS_API_USAGE = """ 2082 const String HOOKS_API_USAGE = """
2069 // The code supports the following hooks: 2083 // The code supports the following hooks:
2070 // dartPrint(message) - if this function is defined it is called 2084 // dartPrint(message) - if this function is defined it is called
2071 // instead of the Dart [print] method. 2085 // instead of the Dart [print] method.
2072 // dartMainRunner(main) - if this function is defined, the Dart [main] 2086 // dartMainRunner(main) - if this function is defined, the Dart [main]
2073 // method will not be invoked directly. 2087 // method will not be invoked directly.
2074 // Instead, a closure that will invoke [main] is 2088 // Instead, a closure that will invoke [main] is
2075 // passed to [dartMainRunner]. 2089 // passed to [dartMainRunner].
2076 """; 2090 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698