OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 import 'package:kernel/frontend/accessors.dart' | 6 import 'package:kernel/frontend/accessors.dart' |
7 show | 7 show |
8 Accessor, | 8 Accessor, |
9 IndexAccessor, | 9 IndexAccessor, |
10 NullAwarePropertyAccessor, | 10 NullAwarePropertyAccessor, |
11 PropertyAccessor, | 11 PropertyAccessor, |
12 ReadOnlyAccessor, | 12 ReadOnlyAccessor, |
13 StaticAccessor, | 13 StaticAccessor, |
14 SuperIndexAccessor, | 14 SuperIndexAccessor, |
15 SuperPropertyAccessor, | 15 SuperPropertyAccessor, |
16 ThisPropertyAccessor, | 16 ThisPropertyAccessor, |
17 VariableAccessor, | 17 VariableAccessor, |
18 buildIsNull, | 18 buildIsNull, |
19 makeBinary, | 19 makeBinary, |
20 makeLet, | 20 makeLet, |
21 makeOrReuseVariable; | 21 makeOrReuseVariable; |
22 | 22 |
| 23 import '../common.dart'; |
23 import '../constants/expressions.dart' | 24 import '../constants/expressions.dart' |
24 show | 25 show |
25 BoolFromEnvironmentConstantExpression, | 26 BoolFromEnvironmentConstantExpression, |
26 ConstantExpression, | 27 ConstantExpression, |
27 ConstructedConstantExpression, | 28 ConstructedConstantExpression, |
28 IntFromEnvironmentConstantExpression, | 29 IntFromEnvironmentConstantExpression, |
29 StringFromEnvironmentConstantExpression, | 30 StringFromEnvironmentConstantExpression, |
30 TypeConstantExpression; | 31 TypeConstantExpression; |
31 import '../dart_types.dart' show DartType, InterfaceType; | 32 import '../dart_types.dart' show DartType, InterfaceType; |
32 import '../diagnostics/spannable.dart' show Spannable; | 33 import '../diagnostics/spannable.dart' show Spannable; |
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 return buildStaticFieldSet(field, rhs); | 1377 return buildStaticFieldSet(field, rhs); |
1377 } | 1378 } |
1378 | 1379 |
1379 @override | 1380 @override |
1380 ir.Expression visitFinalSuperFieldSet( | 1381 ir.Expression visitFinalSuperFieldSet( |
1381 SendSet node, FieldElement field, Node rhs, _) { | 1382 SendSet node, FieldElement field, Node rhs, _) { |
1382 return buildSuperPropertyAccessor(field) | 1383 return buildSuperPropertyAccessor(field) |
1383 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext); | 1384 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext); |
1384 } | 1385 } |
1385 | 1386 |
1386 void addFieldsWithInitializers( | |
1387 ConstructorElement constructor, List<ir.Initializer> initializers) { | |
1388 constructor.enclosingClass.forEachInstanceField((_, FieldElement element) { | |
1389 // Convert the element into the corresponding IR field before asking | |
1390 // if the initializer exists. This is necessary to ensure that the | |
1391 // element has been analyzed before looking at its initializer. | |
1392 ir.Field field = kernel.fieldToIr(element); | |
1393 if (element.initializer != null) { | |
1394 KernelVisitor visitor = | |
1395 new KernelVisitor(element, element.treeElements, kernel); | |
1396 ir.Expression value = visitor.buildInitializer(); | |
1397 initializers.add(new ir.FieldInitializer(field, value)); | |
1398 } | |
1399 }); | |
1400 } | |
1401 | |
1402 IrFunction buildGenerativeConstructor( | 1387 IrFunction buildGenerativeConstructor( |
1403 ConstructorElement constructor, NodeList parameters, Node body) { | 1388 ConstructorElement constructor, NodeList parameters, Node body) { |
1404 List<ir.Initializer> constructorInitializers = <ir.Initializer>[]; | 1389 List<ir.Initializer> constructorInitializers = <ir.Initializer>[]; |
1405 if (kernel.hasHierarchyProblem(constructor.enclosingClass)) { | 1390 if (kernel.hasHierarchyProblem(constructor.enclosingClass)) { |
1406 constructorInitializers.add(new ir.InvalidInitializer()); | 1391 constructorInitializers.add(new ir.InvalidInitializer()); |
1407 } else if (constructor.isSynthesized) { | 1392 } else if (constructor.isSynthesized) { |
1408 List<ir.Expression> arguments = const <ir.Expression>[]; | 1393 List<ir.Expression> arguments = const <ir.Expression>[]; |
1409 List<ir.NamedExpression> named = const <ir.NamedExpression>[]; | 1394 List<ir.NamedExpression> named = const <ir.NamedExpression>[]; |
1410 FunctionSignature signature = constructor.functionSignature; | 1395 FunctionSignature signature = constructor.functionSignature; |
1411 if (signature.parameterCount != 0) { | 1396 if (signature.parameterCount != 0) { |
1412 // Mixin application implicit super call. | 1397 // Mixin application implicit super call. |
1413 arguments = <ir.Expression>[]; | 1398 arguments = <ir.Expression>[]; |
1414 named = <ir.NamedExpression>[]; | 1399 named = <ir.NamedExpression>[]; |
1415 signature.orderedForEachParameter((ParameterElement parameter) { | 1400 signature.orderedForEachParameter((ParameterElement parameter) { |
1416 ir.VariableGet argument = buildLocalGet(parameter); | 1401 ir.VariableGet argument = buildLocalGet(parameter); |
1417 if (parameter.isNamed) { | 1402 if (parameter.isNamed) { |
1418 named.add(new ir.NamedExpression(parameter.name, argument)); | 1403 named.add(new ir.NamedExpression(parameter.name, argument)); |
1419 } else { | 1404 } else { |
1420 arguments.add(argument); | 1405 arguments.add(argument); |
1421 } | 1406 } |
1422 }); | 1407 }); |
1423 } | 1408 } |
1424 if (kernel.isSyntheticError(constructor.definingConstructor)) { | 1409 if (kernel.isSyntheticError(constructor.definingConstructor)) { |
1425 constructorInitializers.add(new ir.InvalidInitializer()); | 1410 constructorInitializers.add(new ir.InvalidInitializer()); |
1426 } else { | 1411 } else { |
1427 addFieldsWithInitializers(constructor, constructorInitializers); | |
1428 constructorInitializers.add(new ir.SuperInitializer( | 1412 constructorInitializers.add(new ir.SuperInitializer( |
1429 kernel.functionToIr(constructor.definingConstructor), | 1413 kernel.functionToIr(constructor.definingConstructor), |
1430 new ir.Arguments(arguments, named: named, types: null))); | 1414 new ir.Arguments(arguments, named: named, types: null))); |
1431 } | 1415 } |
1432 } else { | 1416 } else { |
1433 addFieldsWithInitializers(constructor, constructorInitializers); | |
1434 if (parameters != null) { | 1417 if (parameters != null) { |
1435 // TODO(ahe): the following is a (modified) copy of | 1418 // TODO(ahe): the following is a (modified) copy of |
1436 // [SemanticDeclarationResolvedMixin.visitParameters]. | 1419 // [SemanticDeclarationResolvedMixin.visitParameters]. |
1437 List<ParameterStructure> structures = | 1420 List<ParameterStructure> structures = |
1438 computeParameterStructures(parameters); | 1421 computeParameterStructures(parameters); |
1439 for (ParameterStructure structure in structures) { | 1422 for (ParameterStructure structure in structures) { |
1440 if (structure.parameter.isInitializingFormal) { | 1423 if (structure.parameter.isInitializingFormal) { |
1441 constructorInitializers.add(structure.dispatch(declVisitor, null)); | 1424 constructorInitializers.add(structure.dispatch(declVisitor, null)); |
1442 } | 1425 } |
1443 } | 1426 } |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 if (setterKind == CompoundSetter.INVALID) { | 1935 if (setterKind == CompoundSetter.INVALID) { |
1953 setter = null; | 1936 setter = null; |
1954 } | 1937 } |
1955 return buildStaticAccessor(getter, setter).buildNullAwareAssignment( | 1938 return buildStaticAccessor(getter, setter).buildNullAwareAssignment( |
1956 visitForValue(rhs), | 1939 visitForValue(rhs), |
1957 voidContext: isVoidContext); | 1940 voidContext: isVoidContext); |
1958 } | 1941 } |
1959 | 1942 |
1960 ir.VariableDeclaration getLocal(LocalElement local) { | 1943 ir.VariableDeclaration getLocal(LocalElement local) { |
1961 return locals.putIfAbsent(local, () { | 1944 return locals.putIfAbsent(local, () { |
| 1945 // Currently, initializing formals are not final. |
| 1946 bool isFinal = local.isFinal && !local.isInitializingFormal; |
1962 return associateElement( | 1947 return associateElement( |
1963 new ir.VariableDeclaration(local.name, | 1948 new ir.VariableDeclaration(local.name, |
1964 initializer: null, | 1949 initializer: null, |
1965 type: typeToIrHack(local.type), | 1950 type: typeToIrHack(local.type), |
1966 isFinal: local.isFinal, | 1951 isFinal: isFinal, |
1967 isConst: local.isConst), | 1952 isConst: local.isConst), |
1968 local); | 1953 local); |
1969 }); | 1954 }); |
1970 } | 1955 } |
1971 | 1956 |
1972 ir.FunctionNode buildFunctionNode(FunctionElement function, Node bodyNode) { | 1957 ir.FunctionNode buildFunctionNode(FunctionElement function, Node bodyNode) { |
1973 List<ir.TypeParameter> typeParameters = | 1958 List<ir.TypeParameter> typeParameters = |
1974 kernel.typeParametersNotImplemented(); | 1959 kernel.typeParametersNotImplemented(); |
1975 List<ir.VariableDeclaration> positionalParameters = | 1960 List<ir.VariableDeclaration> positionalParameters = |
1976 <ir.VariableDeclaration>[]; | 1961 <ir.VariableDeclaration>[]; |
(...skipping 13 matching lines...) Expand all Loading... |
1990 }); | 1975 }); |
1991 signature.forEachParameter((ParameterElement parameter) { | 1976 signature.forEachParameter((ParameterElement parameter) { |
1992 if (!parameter.isOptional) return; | 1977 if (!parameter.isOptional) return; |
1993 ir.Expression initializer = visitForValue(parameter.initializer); | 1978 ir.Expression initializer = visitForValue(parameter.initializer); |
1994 ir.VariableDeclaration variable = getLocal(parameter); | 1979 ir.VariableDeclaration variable = getLocal(parameter); |
1995 if (initializer != null) { | 1980 if (initializer != null) { |
1996 variable.initializer = initializer; | 1981 variable.initializer = initializer; |
1997 initializer.parent = variable; | 1982 initializer.parent = variable; |
1998 } | 1983 } |
1999 }); | 1984 }); |
2000 returnType = typeToIrHack(signature.type.returnType); | 1985 if (function.isGenerativeConstructor) { |
| 1986 returnType = const ir.VoidType(); |
| 1987 } else { |
| 1988 returnType = typeToIrHack(signature.type.returnType); |
| 1989 } |
2001 if (function.isFactoryConstructor) { | 1990 if (function.isFactoryConstructor) { |
2002 InterfaceType type = function.enclosingClass.thisType; | 1991 InterfaceType type = function.enclosingClass.thisType; |
2003 if (type.isGeneric) { | 1992 if (type.isGeneric) { |
2004 typeParameters = new List<ir.TypeParameter>(); | 1993 typeParameters = new List<ir.TypeParameter>(); |
2005 for (DartType parameter in type.typeArguments) { | 1994 for (DartType parameter in type.typeArguments) { |
2006 typeParameters.add(kernel.typeVariableToIr(parameter.element)); | 1995 typeParameters.add(kernel.typeVariableToIr(parameter.element)); |
2007 } | 1996 } |
2008 } | 1997 } |
2009 } | 1998 } |
2010 } | 1999 } |
(...skipping 15 matching lines...) Expand all Loading... |
2026 case AsyncMarker.ASYNC_STAR: | 2015 case AsyncMarker.ASYNC_STAR: |
2027 asyncMarker = ir.AsyncMarker.AsyncStar; | 2016 asyncMarker = ir.AsyncMarker.AsyncStar; |
2028 break; | 2017 break; |
2029 | 2018 |
2030 default: | 2019 default: |
2031 internalError( | 2020 internalError( |
2032 function, "Unknown async maker: ${function.asyncMarker}"); | 2021 function, "Unknown async maker: ${function.asyncMarker}"); |
2033 break; | 2022 break; |
2034 } | 2023 } |
2035 } | 2024 } |
2036 ir.Statement body = | 2025 ir.Statement body; |
2037 (bodyNode == null) ? null : buildStatementInBlock(bodyNode); | 2026 if (function.isExternal) { |
| 2027 // [body] must be `null`. |
| 2028 } else if (function.isConstructor) { |
| 2029 // TODO(johnniwinther): Clean this up pending kernel issue #28. |
| 2030 ConstructorElement constructor = function; |
| 2031 if (constructor.isDefaultConstructor) { |
| 2032 body = new ir.EmptyStatement(); |
| 2033 } else if (bodyNode != null && bodyNode.asEmptyStatement() == null) { |
| 2034 body = buildStatementInBlock(bodyNode); |
| 2035 } |
| 2036 } else if (bodyNode != null) { |
| 2037 body = buildStatementInBlock(bodyNode); |
| 2038 } |
2038 return associateElement( | 2039 return associateElement( |
2039 new ir.FunctionNode(body, | 2040 new ir.FunctionNode(body, |
2040 asyncMarker: asyncMarker, | 2041 asyncMarker: asyncMarker, |
2041 returnType: returnType, | 2042 returnType: returnType, |
2042 typeParameters: typeParameters, | 2043 typeParameters: typeParameters, |
2043 positionalParameters: positionalParameters, | 2044 positionalParameters: positionalParameters, |
2044 namedParameters: namedParameters, | 2045 namedParameters: namedParameters, |
2045 requiredParameterCount: requiredParameterCount), | 2046 requiredParameterCount: requiredParameterCount), |
2046 function); | 2047 function); |
2047 } | 2048 } |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 : this(null, true, node, initializers); | 2757 : this(null, true, node, initializers); |
2757 | 2758 |
2758 accept(ir.Visitor v) => throw "unsupported"; | 2759 accept(ir.Visitor v) => throw "unsupported"; |
2759 | 2760 |
2760 visitChildren(ir.Visitor v) => throw "unsupported"; | 2761 visitChildren(ir.Visitor v) => throw "unsupported"; |
2761 | 2762 |
2762 String toString() { | 2763 String toString() { |
2763 return "IrFunction($kind, $isConstructor, $node, $initializers)"; | 2764 return "IrFunction($kind, $isConstructor, $node, $initializers)"; |
2764 } | 2765 } |
2765 } | 2766 } |
OLD | NEW |