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

Side by Side Diff: pkg/kernel/lib/analyzer/ast_from_analyzer.dart

Issue 2680303002: Kernel debugging; service tests (Closed)
Patch Set: Changes based on feedback. Also fixed regress_28443_test Created 3 years, 10 months 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
OLDNEW
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 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 } 517 }
518 518
519 ast.Statement buildMandatoryFunctionBody(FunctionBody body) { 519 ast.Statement buildMandatoryFunctionBody(FunctionBody body) {
520 try { 520 try {
521 if (body is BlockFunctionBody) { 521 if (body is BlockFunctionBody) {
522 return buildStatement(body.block); 522 return buildStatement(body.block);
523 } else if (body is ExpressionFunctionBody) { 523 } else if (body is ExpressionFunctionBody) {
524 if (bodyHasVoidReturn(body)) { 524 if (bodyHasVoidReturn(body)) {
525 return new ast.ExpressionStatement(buildExpression(body.expression)); 525 return new ast.ExpressionStatement(buildExpression(body.expression));
526 } else { 526 } else {
527 return new ast.ReturnStatement(buildExpression(body.expression)); 527 return new ast.ReturnStatement(buildExpression(body.expression))
528 ..fileOffset = body.expression.offset;
528 } 529 }
529 } else { 530 } else {
530 return internalError('Missing function body'); 531 return internalError('Missing function body');
531 } 532 }
532 } on _CompilationError catch (e) { 533 } on _CompilationError catch (e) {
533 return new ast.ExpressionStatement(buildThrowCompileTimeError(e.message)); 534 return new ast.ExpressionStatement(buildThrowCompileTimeError(e.message));
534 } 535 }
535 } 536 }
536 537
537 ast.AsyncMarker getAsyncMarker({bool isAsync: false, bool isStar: false}) { 538 ast.AsyncMarker getAsyncMarker({bool isAsync: false, bool isStar: false}) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 return buildType(element.type); 658 return buildType(element.type);
658 } else if (element is VariableElement) { 659 } else if (element is VariableElement) {
659 return buildType(element.type); 660 return buildType(element.type);
660 } else { 661 } else {
661 log.severe('Unexpected variable element: $element'); 662 log.severe('Unexpected variable element: $element');
662 return const ast.DynamicType(); 663 return const ast.DynamicType();
663 } 664 }
664 } 665 }
665 666
666 ast.VariableDeclaration makeVariableDeclaration(LocalElement element, 667 ast.VariableDeclaration makeVariableDeclaration(LocalElement element,
667 {ast.DartType type, ast.Expression initializer}) { 668 {ast.DartType type, ast.Expression initializer, int equalsOffset}) {
668 var declaration = getVariableReference(element); 669 var declaration = getVariableReference(element);
670 if (equalsOffset != null) declaration.fileEqualsOffset = equalsOffset;
669 declaration.type = type ?? getInferredVariableType(element); 671 declaration.type = type ?? getInferredVariableType(element);
670 if (initializer != null) { 672 if (initializer != null) {
671 declaration.initializer = initializer..parent = declaration; 673 declaration.initializer = initializer..parent = declaration;
672 } 674 }
673 return declaration; 675 return declaration;
674 } 676 }
675 677
676 /// Returns true if [arguments] can be accepted by [target] 678 /// Returns true if [arguments] can be accepted by [target]
677 /// (not taking type checks into account). 679 /// (not taking type checks into account).
678 bool areArgumentsCompatible( 680 bool areArgumentsCompatible(
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 LabeledStatement labeled = node; 956 LabeledStatement labeled = node;
955 node = labeled.statement; 957 node = labeled.statement;
956 } 958 }
957 if (node is VariableDeclarationStatement) { 959 if (node is VariableDeclarationStatement) {
958 VariableDeclarationList list = node.variables; 960 VariableDeclarationList list = node.variables;
959 ast.DartType type = scope.buildOptionalTypeAnnotation(list.type); 961 ast.DartType type = scope.buildOptionalTypeAnnotation(list.type);
960 for (VariableDeclaration decl in list.variables) { 962 for (VariableDeclaration decl in list.variables) {
961 LocalElement local = decl.element as dynamic; // Cross cast. 963 LocalElement local = decl.element as dynamic; // Cross cast.
962 output.add(scope.makeVariableDeclaration(local, 964 output.add(scope.makeVariableDeclaration(local,
963 type: type, 965 type: type,
964 initializer: scope.buildOptionalExpression(decl.initializer))); 966 initializer: scope.buildOptionalExpression(decl.initializer),
967 equalsOffset: decl.equals?.offset));
965 } 968 }
966 } else { 969 } else {
967 output.add(build(node)); 970 output.add(build(node));
968 } 971 }
969 } 972 }
970 973
971 ast.Statement makeBreakTarget(ast.Statement node, LabelStack stackNode) { 974 ast.Statement makeBreakTarget(ast.Statement node, LabelStack stackNode) {
972 if (stackNode.jumps.isEmpty) return node; 975 if (stackNode.jumps.isEmpty) return node;
973 var labeled = new ast.LabeledStatement(node); 976 var labeled = new ast.LabeledStatement(node);
974 for (var jump in stackNode.jumps) { 977 for (var jump in stackNode.jumps) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 ast.Statement visitForStatement(ForStatement node) { 1171 ast.Statement visitForStatement(ForStatement node) {
1169 List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[]; 1172 List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[];
1170 ast.Expression initialExpression; 1173 ast.Expression initialExpression;
1171 if (node.variables != null) { 1174 if (node.variables != null) {
1172 VariableDeclarationList list = node.variables; 1175 VariableDeclarationList list = node.variables;
1173 var type = scope.buildOptionalTypeAnnotation(list.type); 1176 var type = scope.buildOptionalTypeAnnotation(list.type);
1174 for (var variable in list.variables) { 1177 for (var variable in list.variables) {
1175 LocalElement local = variable.element as dynamic; // Cross cast. 1178 LocalElement local = variable.element as dynamic; // Cross cast.
1176 variables.add(scope.makeVariableDeclaration(local, 1179 variables.add(scope.makeVariableDeclaration(local,
1177 initializer: scope.buildOptionalExpression(variable.initializer), 1180 initializer: scope.buildOptionalExpression(variable.initializer),
1178 type: type)); 1181 type: type,
1182 equalsOffset: variable.equals?.offset));
1179 } 1183 }
1180 } else if (node.initialization != null) { 1184 } else if (node.initialization != null) {
1181 initialExpression = scope.buildExpression(node.initialization); 1185 initialExpression = scope.buildExpression(node.initialization);
1182 } 1186 }
1183 var breakNode = new LabelStack.unlabeled(breakStack); 1187 var breakNode = new LabelStack.unlabeled(breakStack);
1184 var continueNode = new LabelStack.unlabeled(continueStack); 1188 var continueNode = new LabelStack.unlabeled(continueStack);
1185 addLoopLabels(node, continueNode); 1189 addLoopLabels(node, continueNode);
1186 var body = buildInScope(node.body, breakNode, continueNode); 1190 var body = buildInScope(node.body, breakNode, continueNode);
1187 var loop = new ast.ForStatement( 1191 var loop = new ast.ForStatement(
1188 variables, 1192 variables,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ { 1361 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ {
1358 final ExpressionScope scope; 1362 final ExpressionScope scope;
1359 ast.VariableDeclaration cascadeReceiver; 1363 ast.VariableDeclaration cascadeReceiver;
1360 ExpressionBuilder(this.scope); 1364 ExpressionBuilder(this.scope);
1361 1365
1362 ast.Expression build(Expression node) { 1366 ast.Expression build(Expression node) {
1363 var result = node.accept(this); 1367 var result = node.accept(this);
1364 if (result is Accessor) { 1368 if (result is Accessor) {
1365 result = result.buildSimpleRead(); 1369 result = result.buildSimpleRead();
1366 } 1370 }
1367 return result..fileOffset = _getOffset(node); 1371 // For some method invocations we have already set a file offset to
1372 // override the default behavior of _getOffset.
1373 if (node is! MethodInvocation || result.fileOffset < 0) {
1374 result.fileOffset = _getOffset(node);
1375 }
1376 return result;
1368 } 1377 }
1369 1378
1370 int _getOffset(AstNode node) { 1379 int _getOffset(AstNode node) {
1371 if (node is MethodInvocation) { 1380 if (node is MethodInvocation) {
1372 return node.methodName.offset; 1381 return node.methodName.offset;
1373 } else if (node is InstanceCreationExpression) { 1382 } else if (node is InstanceCreationExpression) {
1374 return node.constructorName.offset; 1383 return node.constructorName.offset;
1375 } else if (node is BinaryExpression) { 1384 } else if (node is BinaryExpression) {
1376 return node.operator.offset; 1385 return node.operator.offset;
1377 } else if (node is PrefixedIdentifier) { 1386 } else if (node is PrefixedIdentifier) {
1378 return node.identifier.offset; 1387 return node.identifier.offset;
1379 } else if (node is AssignmentExpression) { 1388 } else if (node is AssignmentExpression) {
1380 return _getOffset(node.leftHandSide); 1389 return _getOffset(node.leftHandSide);
1381 } else if (node is PropertyAccess) { 1390 } else if (node is PropertyAccess) {
1382 return node.propertyName.offset; 1391 return node.propertyName.offset;
1383 } else if (node is IsExpression) { 1392 } else if (node is IsExpression) {
1384 return node.isOperator.offset; 1393 return node.isOperator.offset;
1394 } else if (node is AsExpression) {
1395 return node.asOperator.offset;
1385 } else if (node is StringLiteral) { 1396 } else if (node is StringLiteral) {
1386 // Use a catch-all for StringInterpolation and AdjacentStrings: 1397 // Use a catch-all for StringInterpolation and AdjacentStrings:
1387 // the debugger stops at the end. 1398 // the debugger stops at the end.
1388 return node.end; 1399 return node.end;
1400 } else if (node is IndexExpression) {
1401 return node.leftBracket.offset;
1389 } 1402 }
1390 return node.offset; 1403 return node.offset;
1391 } 1404 }
1392 1405
1393 Accessor buildLeftHandValue(Expression node) { 1406 Accessor buildLeftHandValue(Expression node) {
1394 var result = node.accept(this); 1407 var result = node.accept(this);
1395 if (result is Accessor) { 1408 if (result is Accessor) {
1396 return result; 1409 return result;
1397 } else { 1410 } else {
1398 return new ReadOnlyAccessor(result); 1411 return new ReadOnlyAccessor(result);
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 scope.areArgumentsCompatible(element, arguments)) { 1872 scope.areArgumentsCompatible(element, arguments)) {
1860 return new ast.ConstructorInvocation(constructor, arguments, 1873 return new ast.ConstructorInvocation(constructor, arguments,
1861 isConst: node.isConst); 1874 isConst: node.isConst);
1862 } else { 1875 } else {
1863 return noSuchMethodError(); 1876 return noSuchMethodError();
1864 } 1877 }
1865 } 1878 }
1866 1879
1867 ast.Expression visitIsExpression(IsExpression node) { 1880 ast.Expression visitIsExpression(IsExpression node) {
1868 if (node.notOperator != null) { 1881 if (node.notOperator != null) {
1882 // Put offset on the IsExpression for "is!" cases:
1883 // As it is wrapped in a not, it won't get an offset otherwise.
1869 return new ast.Not(new ast.IsExpression( 1884 return new ast.Not(new ast.IsExpression(
1870 build(node.expression), scope.buildTypeAnnotation(node.type))); 1885 build(node.expression), scope.buildTypeAnnotation(node.type))
1886 ..fileOffset = _getOffset(node));
1871 } else { 1887 } else {
1872 return new ast.IsExpression( 1888 return new ast.IsExpression(
1873 build(node.expression), scope.buildTypeAnnotation(node.type)); 1889 build(node.expression), scope.buildTypeAnnotation(node.type));
1874 } 1890 }
1875 } 1891 }
1876 1892
1877 /// Emit a method invocation, either as a direct call `o.f(x)` or decomposed 1893 /// Emit a method invocation, either as a direct call `o.f(x)` or decomposed
1878 /// into a getter and function invocation `o.f.call(x)`. 1894 /// into a getter and function invocation `o.f.call(x)`.
1879 ast.Expression buildDecomposableMethodInvocation(ast.Expression receiver, 1895 ast.Expression buildDecomposableMethodInvocation(ast.Expression receiver,
1880 ast.Name name, ast.Arguments arguments, Element targetElement) { 1896 ast.Name name, ast.Arguments arguments, Element targetElement) {
(...skipping 28 matching lines...) Expand all
1909 scope.buildName(node.methodName), 1925 scope.buildName(node.methodName),
1910 buildArgumentsForInvocation(node), 1926 buildArgumentsForInvocation(node),
1911 element); 1927 element);
1912 } else if (target is SuperExpression) { 1928 } else if (target is SuperExpression) {
1913 scope.addTransformerFlag(TransformerFlag.superCalls); 1929 scope.addTransformerFlag(TransformerFlag.superCalls);
1914 return new ast.SuperMethodInvocation( 1930 return new ast.SuperMethodInvocation(
1915 scope.buildName(node.methodName), 1931 scope.buildName(node.methodName),
1916 buildArgumentsForInvocation(node), 1932 buildArgumentsForInvocation(node),
1917 scope.resolveConcreteMethod(element)); 1933 scope.resolveConcreteMethod(element));
1918 } else if (isLocal(element)) { 1934 } else if (isLocal(element)) {
1935 // Set the offset directly: Normally the offset is at the start of the
1936 // method, but in this case, because we insert a '.call', we want it at
1937 // the end instead.
1919 return new ast.MethodInvocation( 1938 return new ast.MethodInvocation(
1920 new ast.VariableGet(scope.getVariableReference(element)), 1939 new ast.VariableGet(scope.getVariableReference(element)),
1921 callName, 1940 callName,
1922 buildArgumentsForInvocation(node), 1941 buildArgumentsForInvocation(node),
1923 scope.resolveInterfaceFunctionCall(element)); 1942 scope.resolveInterfaceFunctionCall(element))
1943 ..fileOffset = node.methodName.end;
1924 } else if (isStaticMethod(element)) { 1944 } else if (isStaticMethod(element)) {
1925 var method = scope.resolveConcreteMethod(element); 1945 var method = scope.resolveConcreteMethod(element);
1926 var arguments = buildArgumentsForInvocation(node); 1946 var arguments = buildArgumentsForInvocation(node);
1927 if (method == null || !scope.areArgumentsCompatible(element, arguments)) { 1947 if (method == null || !scope.areArgumentsCompatible(element, arguments)) {
1928 return scope.buildThrowNoSuchMethodError( 1948 return scope.buildThrowNoSuchMethodError(
1929 new ast.NullLiteral(), node.methodName.name, arguments, 1949 new ast.NullLiteral(), node.methodName.name, arguments,
1930 candidateTarget: element); 1950 candidateTarget: element);
1931 } 1951 }
1932 return new ast.StaticInvocation(method, arguments); 1952 return new ast.StaticInvocation(method, arguments);
1933 } else if (isStaticVariableOrGetter(element)) { 1953 } else if (isStaticVariableOrGetter(element)) {
1934 var method = scope.resolveConcreteGet(element, null); 1954 var method = scope.resolveConcreteGet(element, null);
1935 if (method == null) { 1955 if (method == null) {
1936 return scope.buildThrowNoSuchMethodError( 1956 return scope.buildThrowNoSuchMethodError(
1937 new ast.NullLiteral(), node.methodName.name, new ast.Arguments([]), 1957 new ast.NullLiteral(), node.methodName.name, new ast.Arguments([]),
1938 candidateTarget: element); 1958 candidateTarget: element);
1939 } 1959 }
1960 // TODO(jensj): We probably want this at the end too.
1940 return new ast.MethodInvocation( 1961 return new ast.MethodInvocation(
1941 new ast.StaticGet(method), 1962 new ast.StaticGet(method),
1942 callName, 1963 callName,
1943 buildArgumentsForInvocation(node), 1964 buildArgumentsForInvocation(node),
1944 scope.resolveInterfaceFunctionCall(element)); 1965 scope.resolveInterfaceFunctionCall(element));
1945 } else if (target == null && !scope.allowThis || 1966 } else if (target == null && !scope.allowThis ||
1946 target is Identifier && target.staticElement is ClassElement || 1967 target is Identifier && target.staticElement is ClassElement ||
1947 target is Identifier && target.staticElement is PrefixElement) { 1968 target is Identifier && target.staticElement is PrefixElement) {
1948 return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(), 1969 return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(),
1949 node.methodName.name, buildArgumentsForInvocation(node), 1970 node.methodName.name, buildArgumentsForInvocation(node),
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 } 2014 }
1994 2015
1995 ast.Expression visitPostfixExpression(PostfixExpression node) { 2016 ast.Expression visitPostfixExpression(PostfixExpression node) {
1996 String operator = node.operator.value(); 2017 String operator = node.operator.value();
1997 switch (operator) { 2018 switch (operator) {
1998 case '++': 2019 case '++':
1999 case '--': 2020 case '--':
2000 var leftHand = buildLeftHandValue(node.operand); 2021 var leftHand = buildLeftHandValue(node.operand);
2001 var binaryOperator = new ast.Name(operator[0]); 2022 var binaryOperator = new ast.Name(operator[0]);
2002 return leftHand.buildPostfixIncrement(binaryOperator, 2023 return leftHand.buildPostfixIncrement(binaryOperator,
2003 offset: node.offset, 2024 offset: node.operator.offset,
2004 voidContext: isInVoidContext(node), 2025 voidContext: isInVoidContext(node),
2005 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); 2026 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
2006 2027
2007 default: 2028 default:
2008 return scope.internalError('Invalid postfix operator $operator'); 2029 return scope.internalError('Invalid postfix operator $operator');
2009 } 2030 }
2010 } 2031 }
2011 2032
2012 ast.Expression visitPrefixExpression(PrefixExpression node) { 2033 ast.Expression visitPrefixExpression(PrefixExpression node) {
2013 String operator = node.operator.value(); 2034 String operator = node.operator.value();
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 if (list[i - 1].compareTo(item) == 0) { 3060 if (list[i - 1].compareTo(item) == 0) {
3040 ++deleted; 3061 ++deleted;
3041 } else if (deleted > 0) { 3062 } else if (deleted > 0) {
3042 list[i - deleted] = item; 3063 list[i - deleted] = item;
3043 } 3064 }
3044 } 3065 }
3045 if (deleted > 0) { 3066 if (deleted > 0) {
3046 list.length -= deleted; 3067 list.length -= deleted;
3047 } 3068 }
3048 } 3069 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698