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

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

Issue 2680303002: Kernel debugging; service tests (Closed)
Patch Set: Correct file offset when calling on field (mind the rebase) 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 // Set the offset directly: Normally the offset is at the start of the
1961 // method, but in this case, because we insert a '.call', we want it at
1962 // the end instead.
1940 return new ast.MethodInvocation( 1963 return new ast.MethodInvocation(
1941 new ast.StaticGet(method), 1964 new ast.StaticGet(method),
1942 callName, 1965 callName,
1943 buildArgumentsForInvocation(node), 1966 buildArgumentsForInvocation(node),
1944 scope.resolveInterfaceFunctionCall(element)); 1967 scope.resolveInterfaceFunctionCall(element))
1968 ..fileOffset = node.methodName.end;
1945 } else if (target == null && !scope.allowThis || 1969 } else if (target == null && !scope.allowThis ||
1946 target is Identifier && target.staticElement is ClassElement || 1970 target is Identifier && target.staticElement is ClassElement ||
1947 target is Identifier && target.staticElement is PrefixElement) { 1971 target is Identifier && target.staticElement is PrefixElement) {
1948 return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(), 1972 return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(),
1949 node.methodName.name, buildArgumentsForInvocation(node), 1973 node.methodName.name, buildArgumentsForInvocation(node),
1950 candidateTarget: element); 1974 candidateTarget: element);
1951 } else if (target == null) { 1975 } else if (target == null) {
1952 return buildDecomposableMethodInvocation( 1976 return buildDecomposableMethodInvocation(
1953 scope.buildThis(), 1977 scope.buildThis(),
1954 scope.buildName(node.methodName), 1978 scope.buildName(node.methodName),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 } 2017 }
1994 2018
1995 ast.Expression visitPostfixExpression(PostfixExpression node) { 2019 ast.Expression visitPostfixExpression(PostfixExpression node) {
1996 String operator = node.operator.value(); 2020 String operator = node.operator.value();
1997 switch (operator) { 2021 switch (operator) {
1998 case '++': 2022 case '++':
1999 case '--': 2023 case '--':
2000 var leftHand = buildLeftHandValue(node.operand); 2024 var leftHand = buildLeftHandValue(node.operand);
2001 var binaryOperator = new ast.Name(operator[0]); 2025 var binaryOperator = new ast.Name(operator[0]);
2002 return leftHand.buildPostfixIncrement(binaryOperator, 2026 return leftHand.buildPostfixIncrement(binaryOperator,
2003 offset: node.offset, 2027 offset: node.operator.offset,
2004 voidContext: isInVoidContext(node), 2028 voidContext: isInVoidContext(node),
2005 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); 2029 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
2006 2030
2007 default: 2031 default:
2008 return scope.internalError('Invalid postfix operator $operator'); 2032 return scope.internalError('Invalid postfix operator $operator');
2009 } 2033 }
2010 } 2034 }
2011 2035
2012 ast.Expression visitPrefixExpression(PrefixExpression node) { 2036 ast.Expression visitPrefixExpression(PrefixExpression node) {
2013 String operator = node.operator.value(); 2037 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) { 3063 if (list[i - 1].compareTo(item) == 0) {
3040 ++deleted; 3064 ++deleted;
3041 } else if (deleted > 0) { 3065 } else if (deleted > 0) {
3042 list[i - deleted] = item; 3066 list[i - deleted] = item;
3043 } 3067 }
3044 } 3068 }
3045 if (deleted > 0) { 3069 if (deleted > 0) {
3046 list.length -= deleted; 3070 list.length -= deleted;
3047 } 3071 }
3048 } 3072 }
OLDNEW
« no previous file with comments | « pkg/kernel/binary.md ('k') | pkg/kernel/lib/ast.dart » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698