Chromium Code Reviews| 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library kernel.analyzer.ast_from_analyzer; | 4 library kernel.analyzer.ast_from_analyzer; |
| 5 | 5 |
| 6 import '../ast.dart' as ast; | 6 import '../ast.dart' as ast; |
| 7 import '../frontend/accessors.dart'; | 7 import '../frontend/accessors.dart'; |
| 8 import '../frontend/super_initializers.dart'; | 8 import '../frontend/super_initializers.dart'; |
| 9 import '../log.dart'; | 9 import '../log.dart'; |
| 10 import '../type_algebra.dart'; | 10 import '../type_algebra.dart'; |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 462 } | 462 } |
| 463 } | 463 } |
| 464 var returnType = element is ConstructorElement | 464 var returnType = element is ConstructorElement |
| 465 ? const ast.VoidType() | 465 ? const ast.VoidType() |
| 466 : buildType(element.returnType); | 466 : buildType(element.returnType); |
| 467 return new ast.FunctionNode(null, | 467 return new ast.FunctionNode(null, |
| 468 typeParameters: typeParameters, | 468 typeParameters: typeParameters, |
| 469 positionalParameters: positional, | 469 positionalParameters: positional, |
| 470 namedParameters: named, | 470 namedParameters: named, |
| 471 requiredParameterCount: requiredParameterCount, | 471 requiredParameterCount: requiredParameterCount, |
| 472 returnType: returnType); | 472 returnType: returnType)..fileOffset = element.nameOffset; |
| 473 } | 473 } |
| 474 } | 474 } |
| 475 | 475 |
| 476 class ExpressionScope extends TypeScope { | 476 class ExpressionScope extends TypeScope { |
| 477 ast.Library currentLibrary; | 477 ast.Library currentLibrary; |
| 478 final Map<LocalElement, ast.VariableDeclaration> localVariables = | 478 final Map<LocalElement, ast.VariableDeclaration> localVariables = |
| 479 <LocalElement, ast.VariableDeclaration>{}; | 479 <LocalElement, ast.VariableDeclaration>{}; |
| 480 | 480 |
| 481 ExpressionBuilder _expressionBuilder; | 481 ExpressionBuilder _expressionBuilder; |
| 482 StatementBuilder _statementBuilder; | 482 StatementBuilder _statementBuilder; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 | 556 |
| 557 case ParameterKind.POSITIONAL: | 557 case ParameterKind.POSITIONAL: |
| 558 positional.add(declaration); | 558 positional.add(declaration); |
| 559 break; | 559 break; |
| 560 | 560 |
| 561 case ParameterKind.NAMED: | 561 case ParameterKind.NAMED: |
| 562 named.add(declaration); | 562 named.add(declaration); |
| 563 break; | 563 break; |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 int offset = formalParameters?.offset ?? body.offset; | |
| 567 // Debug-stop on the "}" of a function, not after. | |
|
Kevin Millikin (Google)
2017/01/04 14:36:58
Debug-stop is not really a word. Can't the end to
jensj
2017/01/05 09:07:55
It was an attempt to explain the use of "endToken.
| |
| 568 int endOffset = body.endToken.offset; | |
| 566 return new ast.FunctionNode(buildOptionalFunctionBody(body), | 569 return new ast.FunctionNode(buildOptionalFunctionBody(body), |
| 567 typeParameters: typeParameters, | 570 typeParameters: typeParameters, |
| 568 positionalParameters: positional, | 571 positionalParameters: positional, |
| 569 namedParameters: named, | 572 namedParameters: named, |
| 570 requiredParameterCount: requiredParameterCount, | 573 requiredParameterCount: requiredParameterCount, |
| 571 returnType: buildOptionalTypeAnnotation(returnType) ?? | 574 returnType: buildOptionalTypeAnnotation(returnType) ?? |
| 572 inferredReturnType ?? | 575 inferredReturnType ?? |
| 573 const ast.DynamicType(), | 576 const ast.DynamicType(), |
| 574 asyncMarker: getAsyncMarker( | 577 asyncMarker: getAsyncMarker( |
| 575 isAsync: body.isAsynchronous, isStar: body.isGenerator)); | 578 isAsync: body.isAsynchronous, isStar: body.isGenerator)) |
| 579 ..fileOffset = offset | |
| 580 ..fileEndOffset = endOffset; | |
| 576 } | 581 } |
| 577 | 582 |
| 578 ast.Expression buildOptionalTopLevelExpression(Expression node) { | 583 ast.Expression buildOptionalTopLevelExpression(Expression node) { |
| 579 return node == null ? null : buildTopLevelExpression(node); | 584 return node == null ? null : buildTopLevelExpression(node); |
| 580 } | 585 } |
| 581 | 586 |
| 582 ast.Expression buildTopLevelExpression(Expression node) { | 587 ast.Expression buildTopLevelExpression(Expression node) { |
| 583 try { | 588 try { |
| 584 return _expressionBuilder.build(node); | 589 return _expressionBuilder.build(node); |
| 585 } on _CompilationError catch (e) { | 590 } on _CompilationError catch (e) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 element is FunctionElement; | 631 element is FunctionElement; |
| 627 } | 632 } |
| 628 | 633 |
| 629 bool isConst(Element element) { | 634 bool isConst(Element element) { |
| 630 return element is VariableElement && element.isConst; | 635 return element is VariableElement && element.isConst; |
| 631 } | 636 } |
| 632 | 637 |
| 633 ast.VariableDeclaration getVariableReference(LocalElement element) { | 638 ast.VariableDeclaration getVariableReference(LocalElement element) { |
| 634 return localVariables.putIfAbsent(element, () { | 639 return localVariables.putIfAbsent(element, () { |
| 635 return new ast.VariableDeclaration(element.name, | 640 return new ast.VariableDeclaration(element.name, |
| 636 isFinal: isFinal(element), isConst: isConst(element)); | 641 isFinal: isFinal(element), |
| 642 isConst: isConst(element))..fileOffset = element.nameOffset; | |
| 637 }); | 643 }); |
| 638 } | 644 } |
| 639 | 645 |
| 640 ast.DartType getInferredVariableType(Element element) { | 646 ast.DartType getInferredVariableType(Element element) { |
| 641 if (!strongMode) return const ast.DynamicType(); | 647 if (!strongMode) return const ast.DynamicType(); |
| 642 if (element is FunctionTypedElement) { | 648 if (element is FunctionTypedElement) { |
| 643 return buildType(element.type); | 649 return buildType(element.type); |
| 644 } else if (element is VariableElement) { | 650 } else if (element is VariableElement) { |
| 645 return buildType(element.type); | 651 return buildType(element.type); |
| 646 } else { | 652 } else { |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 LabelStack.many(this.labels, this.next); | 896 LabelStack.many(this.labels, this.next); |
| 891 } | 897 } |
| 892 | 898 |
| 893 class StatementBuilder extends GeneralizingAstVisitor<ast.Statement> { | 899 class StatementBuilder extends GeneralizingAstVisitor<ast.Statement> { |
| 894 final ExpressionScope scope; | 900 final ExpressionScope scope; |
| 895 LabelStack breakStack, continueStack; | 901 LabelStack breakStack, continueStack; |
| 896 | 902 |
| 897 StatementBuilder(this.scope, [this.breakStack, this.continueStack]); | 903 StatementBuilder(this.scope, [this.breakStack, this.continueStack]); |
| 898 | 904 |
| 899 ast.Statement build(Statement node) { | 905 ast.Statement build(Statement node) { |
| 900 return node.accept(this); | 906 ast.Statement result = node.accept(this); |
| 907 result.fileOffset = _getOffset(node); | |
| 908 return result; | |
| 901 } | 909 } |
| 902 | 910 |
| 903 ast.Statement buildOptional(Statement node) { | 911 ast.Statement buildOptional(Statement node) { |
| 904 return node?.accept(this); | 912 ast.Statement result = node?.accept(this); |
| 913 result?.fileOffset = _getOffset(node); | |
| 914 return result; | |
| 915 } | |
| 916 | |
| 917 int _getOffset(AstNode node) { | |
| 918 return node.offset; | |
| 905 } | 919 } |
| 906 | 920 |
| 907 ast.Statement buildInScope( | 921 ast.Statement buildInScope( |
| 908 Statement node, LabelStack breakNode, LabelStack continueNode) { | 922 Statement node, LabelStack breakNode, LabelStack continueNode) { |
| 909 var oldBreak = this.breakStack; | 923 var oldBreak = this.breakStack; |
| 910 var oldContinue = this.continueStack; | 924 var oldContinue = this.continueStack; |
| 911 breakStack = breakNode; | 925 breakStack = breakNode; |
| 912 continueStack = continueNode; | 926 continueStack = continueNode; |
| 913 var result = build(node); | 927 var result = build(node); |
| 914 this.breakStack = oldBreak; | 928 this.breakStack = oldBreak; |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1275 FunctionDeclarationStatement node) { | 1289 FunctionDeclarationStatement node) { |
| 1276 var declaration = node.functionDeclaration; | 1290 var declaration = node.functionDeclaration; |
| 1277 var expression = declaration.functionExpression; | 1291 var expression = declaration.functionExpression; |
| 1278 LocalElement element = declaration.element as dynamic; // Cross cast. | 1292 LocalElement element = declaration.element as dynamic; // Cross cast. |
| 1279 // TODO: Set a function type on the variable. | 1293 // TODO: Set a function type on the variable. |
| 1280 return new ast.FunctionDeclaration( | 1294 return new ast.FunctionDeclaration( |
| 1281 scope.makeVariableDeclaration(element), | 1295 scope.makeVariableDeclaration(element), |
| 1282 scope.buildFunctionNode(expression.parameters, expression.body, | 1296 scope.buildFunctionNode(expression.parameters, expression.body, |
| 1283 typeParameters: | 1297 typeParameters: |
| 1284 scope.buildOptionalTypeParameterList(expression.typeParameters), | 1298 scope.buildOptionalTypeParameterList(expression.typeParameters), |
| 1285 returnType: declaration.returnType)); | 1299 returnType: declaration.returnType))..fileOffset = node.offset; |
| 1286 } | 1300 } |
| 1287 | 1301 |
| 1288 @override | 1302 @override |
| 1289 visitStatement(Statement node) { | 1303 visitStatement(Statement node) { |
| 1290 return scope.internalError('Unhandled statement ${node.runtimeType}'); | 1304 return scope.internalError('Unhandled statement ${node.runtimeType}'); |
| 1291 } | 1305 } |
| 1292 } | 1306 } |
| 1293 | 1307 |
| 1294 class ExpressionBuilder | 1308 class ExpressionBuilder |
| 1295 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ { | 1309 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1309 if (node is MethodInvocation) { | 1323 if (node is MethodInvocation) { |
| 1310 return node.methodName.offset; | 1324 return node.methodName.offset; |
| 1311 } else if (node is InstanceCreationExpression) { | 1325 } else if (node is InstanceCreationExpression) { |
| 1312 return node.constructorName.offset; | 1326 return node.constructorName.offset; |
| 1313 } else if (node is BinaryExpression) { | 1327 } else if (node is BinaryExpression) { |
| 1314 return node.operator.offset; | 1328 return node.operator.offset; |
| 1315 } else if (node is PrefixedIdentifier) { | 1329 } else if (node is PrefixedIdentifier) { |
| 1316 return node.identifier.offset; | 1330 return node.identifier.offset; |
| 1317 } else if (node is AssignmentExpression) { | 1331 } else if (node is AssignmentExpression) { |
| 1318 return _getOffset(node.leftHandSide); | 1332 return _getOffset(node.leftHandSide); |
| 1333 } else if (node is PropertyAccess) { | |
| 1334 return node.propertyName.offset; | |
| 1335 } else if (node is IsExpression) { | |
| 1336 return node.isOperator.offset; | |
| 1337 } else if (node is StringLiteral) { | |
| 1338 // Use a catch-all for StringInterpolation and AdjacentStrings: | |
|
Kevin Millikin (Google)
2017/01/04 14:36:58
I wouldn't tie this to the debugger, there are a l
jensj
2017/01/05 09:07:55
The reason I put the comment (and tied it to the d
| |
| 1339 // the debugger stops at the end. | |
| 1340 return node.end; | |
| 1319 } | 1341 } |
| 1320 return node.offset; | 1342 return node.offset; |
| 1321 } | 1343 } |
| 1322 | 1344 |
| 1323 Accessor buildLeftHandValue(Expression node) { | 1345 Accessor buildLeftHandValue(Expression node) { |
| 1324 var result = node.accept(this); | 1346 var result = node.accept(this); |
| 1325 if (result is Accessor) { | 1347 if (result is Accessor) { |
| 1326 return result; | 1348 return result; |
| 1327 } else { | 1349 } else { |
| 1328 return new ReadOnlyAccessor(result); | 1350 return new ReadOnlyAccessor(result); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1341 var rightHand = build(node.rightHandSide); | 1363 var rightHand = build(node.rightHandSide); |
| 1342 if (operator == '=') { | 1364 if (operator == '=') { |
| 1343 return leftHand.buildAssignment(rightHand, voidContext: voidContext); | 1365 return leftHand.buildAssignment(rightHand, voidContext: voidContext); |
| 1344 } else if (operator == '??=') { | 1366 } else if (operator == '??=') { |
| 1345 return leftHand.buildNullAwareAssignment( | 1367 return leftHand.buildNullAwareAssignment( |
| 1346 rightHand, scope.buildType(node.staticType), | 1368 rightHand, scope.buildType(node.staticType), |
| 1347 voidContext: voidContext); | 1369 voidContext: voidContext); |
| 1348 } else { | 1370 } else { |
| 1349 // Cut off the trailing '='. | 1371 // Cut off the trailing '='. |
| 1350 var name = new ast.Name(operator.substring(0, operator.length - 1)); | 1372 var name = new ast.Name(operator.substring(0, operator.length - 1)); |
| 1351 return leftHand.buildCompoundAssignment(name, rightHand, | 1373 return leftHand.buildCompoundAssignment(name, rightHand, node.offset, |
| 1352 voidContext: voidContext, | 1374 voidContext: voidContext, |
| 1353 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); | 1375 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); |
| 1354 } | 1376 } |
| 1355 } | 1377 } |
| 1356 | 1378 |
| 1357 ast.Expression visitAwaitExpression(AwaitExpression node) { | 1379 ast.Expression visitAwaitExpression(AwaitExpression node) { |
| 1358 return new ast.AwaitExpression(build(node.expression)); | 1380 return new ast.AwaitExpression(build(node.expression)); |
| 1359 } | 1381 } |
| 1360 | 1382 |
| 1361 ast.Arguments buildSingleArgument(Expression node) { | 1383 ast.Arguments buildSingleArgument(Expression node) { |
| 1362 return new ast.Arguments(<ast.Expression>[build(node)]); | 1384 return new ast.Arguments(<ast.Expression>[build(node)]); |
| 1363 } | 1385 } |
| 1364 | 1386 |
| 1365 ast.Expression visitBinaryExpression(BinaryExpression node) { | 1387 ast.Expression visitBinaryExpression(BinaryExpression node) { |
| 1366 String operator = node.operator.value(); | 1388 String operator = node.operator.value(); |
| 1367 if (operator == '&&' || operator == '||') { | 1389 if (operator == '&&' || operator == '||') { |
| 1368 return new ast.LogicalExpression( | 1390 return new ast.LogicalExpression( |
| 1369 build(node.leftOperand), operator, build(node.rightOperand)); | 1391 build(node.leftOperand), operator, build(node.rightOperand)); |
| 1370 } | 1392 } |
| 1371 if (operator == '??') { | 1393 if (operator == '??') { |
| 1372 ast.Expression leftOperand = build(node.leftOperand); | 1394 ast.Expression leftOperand = build(node.leftOperand); |
| 1373 if (leftOperand is ast.VariableGet) { | 1395 if (leftOperand is ast.VariableGet) { |
| 1374 return new ast.ConditionalExpression( | 1396 return new ast.ConditionalExpression( |
| 1375 buildIsNull(leftOperand), | 1397 buildIsNull(leftOperand, offset: node.leftOperand.offset), |
| 1376 build(node.rightOperand), | 1398 build(node.rightOperand), |
| 1377 new ast.VariableGet(leftOperand.variable), | 1399 new ast.VariableGet(leftOperand.variable), |
| 1378 scope.getInferredType(node)); | 1400 scope.getInferredType(node)); |
| 1379 } else { | 1401 } else { |
| 1380 var variable = new ast.VariableDeclaration.forValue(leftOperand); | 1402 var variable = new ast.VariableDeclaration.forValue(leftOperand); |
| 1381 return new ast.Let( | 1403 return new ast.Let( |
| 1382 variable, | 1404 variable, |
| 1383 new ast.ConditionalExpression( | 1405 new ast.ConditionalExpression( |
| 1384 buildIsNull(new ast.VariableGet(variable)), | 1406 buildIsNull(new ast.VariableGet(variable), |
| 1407 offset: leftOperand.fileOffset), | |
| 1385 build(node.rightOperand), | 1408 build(node.rightOperand), |
| 1386 new ast.VariableGet(variable), | 1409 new ast.VariableGet(variable), |
| 1387 scope.getInferredType(node))); | 1410 scope.getInferredType(node))); |
| 1388 } | 1411 } |
| 1389 } | 1412 } |
| 1390 bool isNegated = false; | 1413 bool isNegated = false; |
| 1391 if (operator == '!=') { | 1414 if (operator == '!=') { |
| 1392 isNegated = true; | 1415 isNegated = true; |
| 1393 operator = '=='; | 1416 operator = '=='; |
| 1394 } | 1417 } |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1878 var receiver = makeOrReuseVariable(build(target)); | 1901 var receiver = makeOrReuseVariable(build(target)); |
| 1879 return makeLet( | 1902 return makeLet( |
| 1880 receiver, | 1903 receiver, |
| 1881 new ast.ConditionalExpression( | 1904 new ast.ConditionalExpression( |
| 1882 buildIsNull(new ast.VariableGet(receiver)), | 1905 buildIsNull(new ast.VariableGet(receiver)), |
| 1883 new ast.NullLiteral(), | 1906 new ast.NullLiteral(), |
| 1884 buildDecomposableMethodInvocation( | 1907 buildDecomposableMethodInvocation( |
| 1885 new ast.VariableGet(receiver), | 1908 new ast.VariableGet(receiver), |
| 1886 scope.buildName(node.methodName), | 1909 scope.buildName(node.methodName), |
| 1887 buildArgumentsForInvocation(node), | 1910 buildArgumentsForInvocation(node), |
| 1888 element), | 1911 element)..fileOffset = node.methodName.offset, |
| 1889 scope.buildType(node.staticType))); | 1912 scope.buildType(node.staticType))); |
| 1890 } else { | 1913 } else { |
| 1891 return buildDecomposableMethodInvocation( | 1914 return buildDecomposableMethodInvocation( |
| 1892 build(node.target), | 1915 build(node.target), |
| 1893 scope.buildName(node.methodName), | 1916 scope.buildName(node.methodName), |
| 1894 buildArgumentsForInvocation(node), | 1917 buildArgumentsForInvocation(node), |
| 1895 element); | 1918 element); |
| 1896 } | 1919 } |
| 1897 } | 1920 } |
| 1898 | 1921 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1912 parent is ExpressionFunctionBody && scope.bodyHasVoidReturn(parent); | 1935 parent is ExpressionFunctionBody && scope.bodyHasVoidReturn(parent); |
| 1913 } | 1936 } |
| 1914 | 1937 |
| 1915 ast.Expression visitPostfixExpression(PostfixExpression node) { | 1938 ast.Expression visitPostfixExpression(PostfixExpression node) { |
| 1916 String operator = node.operator.value(); | 1939 String operator = node.operator.value(); |
| 1917 switch (operator) { | 1940 switch (operator) { |
| 1918 case '++': | 1941 case '++': |
| 1919 case '--': | 1942 case '--': |
| 1920 var leftHand = buildLeftHandValue(node.operand); | 1943 var leftHand = buildLeftHandValue(node.operand); |
| 1921 var binaryOperator = new ast.Name(operator[0]); | 1944 var binaryOperator = new ast.Name(operator[0]); |
| 1922 return leftHand.buildPostfixIncrement(binaryOperator, | 1945 return leftHand.buildPostfixIncrement(binaryOperator, node.offset, |
| 1923 voidContext: isInVoidContext(node), | 1946 voidContext: isInVoidContext(node), |
| 1924 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); | 1947 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); |
| 1925 | 1948 |
| 1926 default: | 1949 default: |
| 1927 return scope.internalError('Invalid postfix operator $operator'); | 1950 return scope.internalError('Invalid postfix operator $operator'); |
| 1928 } | 1951 } |
| 1929 } | 1952 } |
| 1930 | 1953 |
| 1931 ast.Expression visitPrefixExpression(PrefixExpression node) { | 1954 ast.Expression visitPrefixExpression(PrefixExpression node) { |
| 1932 String operator = node.operator.value(); | 1955 String operator = node.operator.value(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1945 new ast.Arguments.empty(), | 1968 new ast.Arguments.empty(), |
| 1946 scope.resolveInterfaceMethod(node.staticElement)); | 1969 scope.resolveInterfaceMethod(node.staticElement)); |
| 1947 | 1970 |
| 1948 case '!': | 1971 case '!': |
| 1949 return new ast.Not(build(node.operand)); | 1972 return new ast.Not(build(node.operand)); |
| 1950 | 1973 |
| 1951 case '++': | 1974 case '++': |
| 1952 case '--': | 1975 case '--': |
| 1953 var leftHand = buildLeftHandValue(node.operand); | 1976 var leftHand = buildLeftHandValue(node.operand); |
| 1954 var binaryOperator = new ast.Name(operator[0]); | 1977 var binaryOperator = new ast.Name(operator[0]); |
| 1955 return leftHand.buildPrefixIncrement(binaryOperator, | 1978 return leftHand.buildPrefixIncrement(binaryOperator, node.offset, |
| 1956 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); | 1979 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); |
| 1957 | 1980 |
| 1958 default: | 1981 default: |
| 1959 return scope.internalError('Invalid prefix operator $operator'); | 1982 return scope.internalError('Invalid prefix operator $operator'); |
| 1960 } | 1983 } |
| 1961 } | 1984 } |
| 1962 | 1985 |
| 1963 visitPropertyAccess(PropertyAccess node) { | 1986 visitPropertyAccess(PropertyAccess node) { |
| 1964 Element element = node.propertyName.staticElement; | 1987 Element element = node.propertyName.staticElement; |
| 1965 Element auxiliary = node.propertyName.auxiliaryElements?.staticElement; | 1988 Element auxiliary = node.propertyName.auxiliaryElements?.staticElement; |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2325 node.accept(this); | 2348 node.accept(this); |
| 2326 } | 2349 } |
| 2327 | 2350 |
| 2328 /// Builds an empty class for broken classes that have no AST. | 2351 /// Builds an empty class for broken classes that have no AST. |
| 2329 /// | 2352 /// |
| 2330 /// This should only be used to recover from a compile-time error. | 2353 /// This should only be used to recover from a compile-time error. |
| 2331 void buildBrokenClass() { | 2354 void buildBrokenClass() { |
| 2332 currentClass.name = element.name; | 2355 currentClass.name = element.name; |
| 2333 currentClass.supertype = scope.getRootClassReference().asRawSupertype; | 2356 currentClass.supertype = scope.getRootClassReference().asRawSupertype; |
| 2334 currentClass.constructors.add( | 2357 currentClass.constructors.add( |
| 2335 new ast.Constructor(new ast.FunctionNode(new ast.InvalidStatement()))); | 2358 new ast.Constructor(new ast.FunctionNode(new ast.InvalidStatement())) |
| 2359 ..fileOffset = element.nameOffset); | |
| 2336 } | 2360 } |
| 2337 | 2361 |
| 2338 void addAnnotations(List<Annotation> annotations) { | 2362 void addAnnotations(List<Annotation> annotations) { |
| 2339 // Class type parameters are not in scope in the annotation list. | 2363 // Class type parameters are not in scope in the annotation list. |
| 2340 for (var annotation in annotations) { | 2364 for (var annotation in annotations) { |
| 2341 currentClass.addAnnotation(annotationScope.buildAnnotation(annotation)); | 2365 currentClass.addAnnotation(annotationScope.buildAnnotation(annotation)); |
| 2342 } | 2366 } |
| 2343 } | 2367 } |
| 2344 | 2368 |
| 2345 void _buildMemberBody(ast.Member member, Element element, AstNode node) { | 2369 void _buildMemberBody(ast.Member member, Element element, AstNode node) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2474 var parameter = new ast.VariableDeclaration('index', type: intType); | 2498 var parameter = new ast.VariableDeclaration('index', type: intType); |
| 2475 var function = new ast.FunctionNode(new ast.EmptyStatement(), | 2499 var function = new ast.FunctionNode(new ast.EmptyStatement(), |
| 2476 positionalParameters: [parameter]); | 2500 positionalParameters: [parameter]); |
| 2477 var superConstructor = scope.loader.getRootClassConstructorReference(); | 2501 var superConstructor = scope.loader.getRootClassConstructorReference(); |
| 2478 var constructor = new ast.Constructor(function, | 2502 var constructor = new ast.Constructor(function, |
| 2479 name: new ast.Name(''), | 2503 name: new ast.Name(''), |
| 2480 isConst: true, | 2504 isConst: true, |
| 2481 initializers: [ | 2505 initializers: [ |
| 2482 new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)), | 2506 new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)), |
| 2483 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) | 2507 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) |
| 2484 ]); | 2508 ])..fileOffset = element.nameOffset; |
| 2485 classNode.addMember(constructor); | 2509 classNode.addMember(constructor); |
| 2486 int index = 0; | 2510 int index = 0; |
| 2487 var enumConstantFields = <ast.Field>[]; | 2511 var enumConstantFields = <ast.Field>[]; |
| 2488 for (var constant in node.constants) { | 2512 for (var constant in node.constants) { |
| 2489 ast.Field field = scope.getMemberReference(constant.element); | 2513 ast.Field field = scope.getMemberReference(constant.element); |
| 2490 field.initializer = new ast.ConstructorInvocation( | 2514 field.initializer = new ast.ConstructorInvocation( |
| 2491 constructor, new ast.Arguments([new ast.IntLiteral(index)]), | 2515 constructor, new ast.Arguments([new ast.IntLiteral(index)]), |
| 2492 isConst: true)..parent = field; | 2516 isConst: true)..parent = field; |
| 2493 field.type = classNode.rawType; | 2517 field.type = classNode.rawType; |
| 2494 classNode.addMember(field); | 2518 classNode.addMember(field); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2550 final MemberScope scope; | 2574 final MemberScope scope; |
| 2551 final Element element; | 2575 final Element element; |
| 2552 ast.Member get currentMember => scope.currentMember; | 2576 ast.Member get currentMember => scope.currentMember; |
| 2553 | 2577 |
| 2554 MemberBodyBuilder( | 2578 MemberBodyBuilder( |
| 2555 ReferenceLevelLoader loader, ast.Member member, this.element) | 2579 ReferenceLevelLoader loader, ast.Member member, this.element) |
| 2556 : scope = new MemberScope(loader, member); | 2580 : scope = new MemberScope(loader, member); |
| 2557 | 2581 |
| 2558 void build(AstNode node) { | 2582 void build(AstNode node) { |
| 2559 if (node != null) { | 2583 if (node != null) { |
| 2584 // Debug-stop on the "}" of a member, not after. | |
|
Kevin Millikin (Google)
2017/01/04 14:36:58
Same comment as above.
jensj
2017/01/05 09:07:55
I'll remove that too.
| |
| 2585 currentMember.fileEndOffset = node.endToken.offset; | |
| 2560 node.accept(this); | 2586 node.accept(this); |
| 2561 } else { | 2587 } else { |
| 2562 buildBrokenMember(); | 2588 buildBrokenMember(); |
| 2563 } | 2589 } |
| 2564 } | 2590 } |
| 2565 | 2591 |
| 2566 /// Builds an empty member. | 2592 /// Builds an empty member. |
| 2567 /// | 2593 /// |
| 2568 /// This should only be used to recover from a compile-time error. | 2594 /// This should only be used to recover from a compile-time error. |
| 2569 void buildBrokenMember() { | 2595 void buildBrokenMember() { |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2844 if (list[i - 1].compareTo(item) == 0) { | 2870 if (list[i - 1].compareTo(item) == 0) { |
| 2845 ++deleted; | 2871 ++deleted; |
| 2846 } else if (deleted > 0) { | 2872 } else if (deleted > 0) { |
| 2847 list[i - deleted] = item; | 2873 list[i - deleted] = item; |
| 2848 } | 2874 } |
| 2849 } | 2875 } |
| 2850 if (deleted > 0) { | 2876 if (deleted > 0) { |
| 2851 list.length -= deleted; | 2877 list.length -= deleted; |
| 2852 } | 2878 } |
| 2853 } | 2879 } |
| OLD | NEW |