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

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

Issue 2680303002: Kernel debugging; service tests (Closed)
Patch Set: Address comments Created 3 years, 9 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
« no previous file with comments | « pkg/kernel/binary.md ('k') | pkg/kernel/lib/ast.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 521 }
522 522
523 ast.Statement buildMandatoryFunctionBody(FunctionBody body) { 523 ast.Statement buildMandatoryFunctionBody(FunctionBody body) {
524 try { 524 try {
525 if (body is BlockFunctionBody) { 525 if (body is BlockFunctionBody) {
526 return buildStatement(body.block); 526 return buildStatement(body.block);
527 } else if (body is ExpressionFunctionBody) { 527 } else if (body is ExpressionFunctionBody) {
528 if (bodyHasVoidReturn(body)) { 528 if (bodyHasVoidReturn(body)) {
529 return new ast.ExpressionStatement(buildExpression(body.expression)); 529 return new ast.ExpressionStatement(buildExpression(body.expression));
530 } else { 530 } else {
531 return new ast.ReturnStatement(buildExpression(body.expression)); 531 return new ast.ReturnStatement(buildExpression(body.expression))
532 ..fileOffset = body.expression.offset;
532 } 533 }
533 } else { 534 } else {
534 return internalError('Missing function body'); 535 return internalError('Missing function body');
535 } 536 }
536 } on _CompilationError catch (e) { 537 } on _CompilationError catch (e) {
537 return new ast.ExpressionStatement(buildThrowCompileTimeError(e.message)); 538 return new ast.ExpressionStatement(buildThrowCompileTimeError(e.message));
538 } 539 }
539 } 540 }
540 541
541 ast.AsyncMarker getAsyncMarker({bool isAsync: false, bool isStar: false}) { 542 ast.AsyncMarker getAsyncMarker({bool isAsync: false, bool isStar: false}) {
(...skipping 29 matching lines...) Expand all
571 positional.add(declaration); 572 positional.add(declaration);
572 break; 573 break;
573 574
574 case ParameterKind.NAMED: 575 case ParameterKind.NAMED:
575 named.add(declaration); 576 named.add(declaration);
576 break; 577 break;
577 } 578 }
578 } 579 }
579 int offset = formalParameters?.offset ?? body.offset; 580 int offset = formalParameters?.offset ?? body.offset;
580 int endOffset = body.endToken.offset; 581 int endOffset = body.endToken.offset;
581 ast.AsyncMarker asyncMarker = getAsyncMarker( 582 ast.AsyncMarker asyncMarker =
582 isAsync: body.isAsynchronous, isStar: body.isGenerator); 583 getAsyncMarker(isAsync: body.isAsynchronous, isStar: body.isGenerator);
583 return new ast.FunctionNode(buildOptionalFunctionBody(body), 584 return new ast.FunctionNode(buildOptionalFunctionBody(body),
584 typeParameters: typeParameters, 585 typeParameters: typeParameters,
585 positionalParameters: positional, 586 positionalParameters: positional,
586 namedParameters: named, 587 namedParameters: named,
587 requiredParameterCount: requiredParameterCount, 588 requiredParameterCount: requiredParameterCount,
588 returnType: buildOptionalTypeAnnotation(returnType) ?? 589 returnType: buildOptionalTypeAnnotation(returnType) ??
589 inferredReturnType ?? 590 inferredReturnType ??
590 const ast.DynamicType(), 591 const ast.DynamicType(),
591 asyncMarker: asyncMarker, 592 asyncMarker: asyncMarker,
592 dartAsyncMarker: asyncMarker) 593 dartAsyncMarker: asyncMarker)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 return buildType(element.type); 664 return buildType(element.type);
664 } else if (element is VariableElement) { 665 } else if (element is VariableElement) {
665 return buildType(element.type); 666 return buildType(element.type);
666 } else { 667 } else {
667 log.severe('Unexpected variable element: $element'); 668 log.severe('Unexpected variable element: $element');
668 return const ast.DynamicType(); 669 return const ast.DynamicType();
669 } 670 }
670 } 671 }
671 672
672 ast.VariableDeclaration makeVariableDeclaration(LocalElement element, 673 ast.VariableDeclaration makeVariableDeclaration(LocalElement element,
673 {ast.DartType type, ast.Expression initializer}) { 674 {ast.DartType type, ast.Expression initializer, int equalsOffset}) {
674 var declaration = getVariableReference(element); 675 var declaration = getVariableReference(element);
676 if (equalsOffset != null) declaration.fileEqualsOffset = equalsOffset;
675 declaration.type = type ?? getInferredVariableType(element); 677 declaration.type = type ?? getInferredVariableType(element);
676 if (initializer != null) { 678 if (initializer != null) {
677 declaration.initializer = initializer..parent = declaration; 679 declaration.initializer = initializer..parent = declaration;
678 } 680 }
679 return declaration; 681 return declaration;
680 } 682 }
681 683
682 /// Returns true if [arguments] can be accepted by [target] 684 /// Returns true if [arguments] can be accepted by [target]
683 /// (not taking type checks into account). 685 /// (not taking type checks into account).
684 bool areArgumentsCompatible( 686 bool areArgumentsCompatible(
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 LabeledStatement labeled = node; 962 LabeledStatement labeled = node;
961 node = labeled.statement; 963 node = labeled.statement;
962 } 964 }
963 if (node is VariableDeclarationStatement) { 965 if (node is VariableDeclarationStatement) {
964 VariableDeclarationList list = node.variables; 966 VariableDeclarationList list = node.variables;
965 ast.DartType type = scope.buildOptionalTypeAnnotation(list.type); 967 ast.DartType type = scope.buildOptionalTypeAnnotation(list.type);
966 for (VariableDeclaration decl in list.variables) { 968 for (VariableDeclaration decl in list.variables) {
967 LocalElement local = decl.element as dynamic; // Cross cast. 969 LocalElement local = decl.element as dynamic; // Cross cast.
968 output.add(scope.makeVariableDeclaration(local, 970 output.add(scope.makeVariableDeclaration(local,
969 type: type, 971 type: type,
970 initializer: scope.buildOptionalExpression(decl.initializer))); 972 initializer: scope.buildOptionalExpression(decl.initializer),
973 equalsOffset: decl.equals?.offset));
971 } 974 }
972 } else { 975 } else {
973 output.add(build(node)); 976 output.add(build(node));
974 } 977 }
975 } 978 }
976 979
977 ast.Statement makeBreakTarget(ast.Statement node, LabelStack stackNode) { 980 ast.Statement makeBreakTarget(ast.Statement node, LabelStack stackNode) {
978 if (stackNode.jumps.isEmpty) return node; 981 if (stackNode.jumps.isEmpty) return node;
979 var labeled = new ast.LabeledStatement(node); 982 var labeled = new ast.LabeledStatement(node);
980 for (var jump in stackNode.jumps) { 983 for (var jump in stackNode.jumps) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 ast.Statement visitForStatement(ForStatement node) { 1177 ast.Statement visitForStatement(ForStatement node) {
1175 List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[]; 1178 List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[];
1176 ast.Expression initialExpression; 1179 ast.Expression initialExpression;
1177 if (node.variables != null) { 1180 if (node.variables != null) {
1178 VariableDeclarationList list = node.variables; 1181 VariableDeclarationList list = node.variables;
1179 var type = scope.buildOptionalTypeAnnotation(list.type); 1182 var type = scope.buildOptionalTypeAnnotation(list.type);
1180 for (var variable in list.variables) { 1183 for (var variable in list.variables) {
1181 LocalElement local = variable.element as dynamic; // Cross cast. 1184 LocalElement local = variable.element as dynamic; // Cross cast.
1182 variables.add(scope.makeVariableDeclaration(local, 1185 variables.add(scope.makeVariableDeclaration(local,
1183 initializer: scope.buildOptionalExpression(variable.initializer), 1186 initializer: scope.buildOptionalExpression(variable.initializer),
1184 type: type)); 1187 type: type,
1188 equalsOffset: variable.equals?.offset));
1185 } 1189 }
1186 } else if (node.initialization != null) { 1190 } else if (node.initialization != null) {
1187 initialExpression = scope.buildExpression(node.initialization); 1191 initialExpression = scope.buildExpression(node.initialization);
1188 } 1192 }
1189 var breakNode = new LabelStack.unlabeled(breakStack); 1193 var breakNode = new LabelStack.unlabeled(breakStack);
1190 var continueNode = new LabelStack.unlabeled(continueStack); 1194 var continueNode = new LabelStack.unlabeled(continueStack);
1191 addLoopLabels(node, continueNode); 1195 addLoopLabels(node, continueNode);
1192 var body = buildInScope(node.body, breakNode, continueNode); 1196 var body = buildInScope(node.body, breakNode, continueNode);
1193 var loop = new ast.ForStatement( 1197 var loop = new ast.ForStatement(
1194 variables, 1198 variables,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ { 1367 extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ {
1364 final ExpressionScope scope; 1368 final ExpressionScope scope;
1365 ast.VariableDeclaration cascadeReceiver; 1369 ast.VariableDeclaration cascadeReceiver;
1366 ExpressionBuilder(this.scope); 1370 ExpressionBuilder(this.scope);
1367 1371
1368 ast.Expression build(Expression node) { 1372 ast.Expression build(Expression node) {
1369 var result = node.accept(this); 1373 var result = node.accept(this);
1370 if (result is Accessor) { 1374 if (result is Accessor) {
1371 result = result.buildSimpleRead(); 1375 result = result.buildSimpleRead();
1372 } 1376 }
1373 return result..fileOffset = _getOffset(node); 1377 // For some method invocations we have already set a file offset to
1378 // override the default behavior of _getOffset.
1379 if (node is! MethodInvocation || result.fileOffset < 0) {
1380 result.fileOffset = _getOffset(node);
1381 }
1382 return result;
1374 } 1383 }
1375 1384
1376 int _getOffset(AstNode node) { 1385 int _getOffset(AstNode node) {
1377 if (node is MethodInvocation) { 1386 if (node is MethodInvocation) {
1378 return node.methodName.offset; 1387 return node.methodName.offset;
1379 } else if (node is InstanceCreationExpression) { 1388 } else if (node is InstanceCreationExpression) {
1380 return node.constructorName.offset; 1389 return node.constructorName.offset;
1381 } else if (node is BinaryExpression) { 1390 } else if (node is BinaryExpression) {
1382 return node.operator.offset; 1391 return node.operator.offset;
1383 } else if (node is PrefixedIdentifier) { 1392 } else if (node is PrefixedIdentifier) {
1384 return node.identifier.offset; 1393 return node.identifier.offset;
1385 } else if (node is AssignmentExpression) { 1394 } else if (node is AssignmentExpression) {
1386 return _getOffset(node.leftHandSide); 1395 return _getOffset(node.leftHandSide);
1387 } else if (node is PropertyAccess) { 1396 } else if (node is PropertyAccess) {
1388 return node.propertyName.offset; 1397 return node.propertyName.offset;
1389 } else if (node is IsExpression) { 1398 } else if (node is IsExpression) {
1390 return node.isOperator.offset; 1399 return node.isOperator.offset;
1400 } else if (node is AsExpression) {
1401 return node.asOperator.offset;
1391 } else if (node is StringLiteral) { 1402 } else if (node is StringLiteral) {
1392 // Use a catch-all for StringInterpolation and AdjacentStrings: 1403 // Use a catch-all for StringInterpolation and AdjacentStrings:
1393 // the debugger stops at the end. 1404 // the debugger stops at the end.
1394 return node.end; 1405 return node.end;
1406 } else if (node is IndexExpression) {
1407 return node.leftBracket.offset;
1395 } 1408 }
1396 return node.offset; 1409 return node.offset;
1397 } 1410 }
1398 1411
1399 Accessor buildLeftHandValue(Expression node) { 1412 Accessor buildLeftHandValue(Expression node) {
1400 var result = node.accept(this); 1413 var result = node.accept(this);
1401 if (result is Accessor) { 1414 if (result is Accessor) {
1402 return result; 1415 return result;
1403 } else { 1416 } else {
1404 return new ReadOnlyAccessor(result); 1417 return new ReadOnlyAccessor(result);
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 scope.areArgumentsCompatible(element, arguments)) { 1878 scope.areArgumentsCompatible(element, arguments)) {
1866 return new ast.ConstructorInvocation(constructor, arguments, 1879 return new ast.ConstructorInvocation(constructor, arguments,
1867 isConst: node.isConst); 1880 isConst: node.isConst);
1868 } else { 1881 } else {
1869 return noSuchMethodError(); 1882 return noSuchMethodError();
1870 } 1883 }
1871 } 1884 }
1872 1885
1873 ast.Expression visitIsExpression(IsExpression node) { 1886 ast.Expression visitIsExpression(IsExpression node) {
1874 if (node.notOperator != null) { 1887 if (node.notOperator != null) {
1888 // Put offset on the IsExpression for "is!" cases:
1889 // As it is wrapped in a not, it won't get an offset otherwise.
1875 return new ast.Not(new ast.IsExpression( 1890 return new ast.Not(new ast.IsExpression(
1876 build(node.expression), scope.buildTypeAnnotation(node.type))); 1891 build(node.expression), scope.buildTypeAnnotation(node.type))
1892 ..fileOffset = _getOffset(node));
1877 } else { 1893 } else {
1878 return new ast.IsExpression( 1894 return new ast.IsExpression(
1879 build(node.expression), scope.buildTypeAnnotation(node.type)); 1895 build(node.expression), scope.buildTypeAnnotation(node.type));
1880 } 1896 }
1881 } 1897 }
1882 1898
1883 /// Emit a method invocation, either as a direct call `o.f(x)` or decomposed 1899 /// Emit a method invocation, either as a direct call `o.f(x)` or decomposed
1884 /// into a getter and function invocation `o.f.call(x)`. 1900 /// into a getter and function invocation `o.f.call(x)`.
1885 ast.Expression buildDecomposableMethodInvocation(ast.Expression receiver, 1901 ast.Expression buildDecomposableMethodInvocation(ast.Expression receiver,
1886 ast.Name name, ast.Arguments arguments, Element targetElement) { 1902 ast.Name name, ast.Arguments arguments, Element targetElement) {
(...skipping 28 matching lines...) Expand all
1915 scope.buildName(node.methodName), 1931 scope.buildName(node.methodName),
1916 buildArgumentsForInvocation(node), 1932 buildArgumentsForInvocation(node),
1917 element); 1933 element);
1918 } else if (target is SuperExpression) { 1934 } else if (target is SuperExpression) {
1919 scope.addTransformerFlag(TransformerFlag.superCalls); 1935 scope.addTransformerFlag(TransformerFlag.superCalls);
1920 return new ast.SuperMethodInvocation( 1936 return new ast.SuperMethodInvocation(
1921 scope.buildName(node.methodName), 1937 scope.buildName(node.methodName),
1922 buildArgumentsForInvocation(node), 1938 buildArgumentsForInvocation(node),
1923 scope.resolveConcreteMethod(element)); 1939 scope.resolveConcreteMethod(element));
1924 } else if (isLocal(element)) { 1940 } else if (isLocal(element)) {
1941 // Set the offset directly: Normally the offset is at the start of the
1942 // method, but in this case, because we insert a '.call', we want it at
1943 // the end instead.
1925 return new ast.MethodInvocation( 1944 return new ast.MethodInvocation(
1926 new ast.VariableGet(scope.getVariableReference(element)), 1945 new ast.VariableGet(scope.getVariableReference(element)),
1927 callName, 1946 callName,
1928 buildArgumentsForInvocation(node), 1947 buildArgumentsForInvocation(node),
1929 scope.resolveInterfaceFunctionCall(element)); 1948 scope.resolveInterfaceFunctionCall(element))
1949 ..fileOffset = node.methodName.end;
1930 } else if (isStaticMethod(element)) { 1950 } else if (isStaticMethod(element)) {
1931 var method = scope.resolveConcreteMethod(element); 1951 var method = scope.resolveConcreteMethod(element);
1932 var arguments = buildArgumentsForInvocation(node); 1952 var arguments = buildArgumentsForInvocation(node);
1933 if (method == null || !scope.areArgumentsCompatible(element, arguments)) { 1953 if (method == null || !scope.areArgumentsCompatible(element, arguments)) {
1934 return scope.buildThrowNoSuchMethodError( 1954 return scope.buildThrowNoSuchMethodError(
1935 new ast.NullLiteral(), node.methodName.name, arguments, 1955 new ast.NullLiteral(), node.methodName.name, arguments,
1936 candidateTarget: element); 1956 candidateTarget: element);
1937 } 1957 }
1938 return new ast.StaticInvocation(method, arguments); 1958 return new ast.StaticInvocation(method, arguments);
1939 } else if (isStaticVariableOrGetter(element)) { 1959 } else if (isStaticVariableOrGetter(element)) {
1940 var method = scope.resolveConcreteGet(element, null); 1960 var method = scope.resolveConcreteGet(element, null);
1941 if (method == null) { 1961 if (method == null) {
1942 return scope.buildThrowNoSuchMethodError( 1962 return scope.buildThrowNoSuchMethodError(
1943 new ast.NullLiteral(), node.methodName.name, new ast.Arguments([]), 1963 new ast.NullLiteral(), node.methodName.name, new ast.Arguments([]),
1944 candidateTarget: element); 1964 candidateTarget: element);
1945 } 1965 }
1966 // Set the offset directly: Normally the offset is at the start of the
1967 // method, but in this case, because we insert a '.call', we want it at
1968 // the end instead.
1946 return new ast.MethodInvocation( 1969 return new ast.MethodInvocation(
1947 new ast.StaticGet(method), 1970 new ast.StaticGet(method),
1948 callName, 1971 callName,
1949 buildArgumentsForInvocation(node), 1972 buildArgumentsForInvocation(node),
1950 scope.resolveInterfaceFunctionCall(element)); 1973 scope.resolveInterfaceFunctionCall(element))
1974 ..fileOffset = node.methodName.end;
1951 } else if (target == null && !scope.allowThis || 1975 } else if (target == null && !scope.allowThis ||
1952 target is Identifier && target.staticElement is ClassElement || 1976 target is Identifier && target.staticElement is ClassElement ||
1953 target is Identifier && target.staticElement is PrefixElement) { 1977 target is Identifier && target.staticElement is PrefixElement) {
1954 return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(), 1978 return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(),
1955 node.methodName.name, buildArgumentsForInvocation(node), 1979 node.methodName.name, buildArgumentsForInvocation(node),
1956 candidateTarget: element); 1980 candidateTarget: element);
1957 } else if (target == null) { 1981 } else if (target == null) {
1958 return buildDecomposableMethodInvocation( 1982 return buildDecomposableMethodInvocation(
1959 scope.buildThis(), 1983 scope.buildThis(),
1960 scope.buildName(node.methodName), 1984 scope.buildName(node.methodName),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 } 2023 }
2000 2024
2001 ast.Expression visitPostfixExpression(PostfixExpression node) { 2025 ast.Expression visitPostfixExpression(PostfixExpression node) {
2002 String operator = node.operator.value(); 2026 String operator = node.operator.value();
2003 switch (operator) { 2027 switch (operator) {
2004 case '++': 2028 case '++':
2005 case '--': 2029 case '--':
2006 var leftHand = buildLeftHandValue(node.operand); 2030 var leftHand = buildLeftHandValue(node.operand);
2007 var binaryOperator = new ast.Name(operator[0]); 2031 var binaryOperator = new ast.Name(operator[0]);
2008 return leftHand.buildPostfixIncrement(binaryOperator, 2032 return leftHand.buildPostfixIncrement(binaryOperator,
2009 offset: node.offset, 2033 offset: node.operator.offset,
2010 voidContext: isInVoidContext(node), 2034 voidContext: isInVoidContext(node),
2011 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement)); 2035 interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
2012 2036
2013 default: 2037 default:
2014 return scope.internalError('Invalid postfix operator $operator'); 2038 return scope.internalError('Invalid postfix operator $operator');
2015 } 2039 }
2016 } 2040 }
2017 2041
2018 ast.Expression visitPrefixExpression(PrefixExpression node) { 2042 ast.Expression visitPrefixExpression(PrefixExpression node) {
2019 String operator = node.operator.value(); 2043 String operator = node.operator.value();
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after
3046 if (list[i - 1].compareTo(item) == 0) { 3070 if (list[i - 1].compareTo(item) == 0) {
3047 ++deleted; 3071 ++deleted;
3048 } else if (deleted > 0) { 3072 } else if (deleted > 0) {
3049 list[i - deleted] = item; 3073 list[i - deleted] = item;
3050 } 3074 }
3051 } 3075 }
3052 if (deleted > 0) { 3076 if (deleted > 0) {
3053 list.length -= deleted; 3077 list.length -= deleted;
3054 } 3078 }
3055 } 3079 }
OLDNEW
« no previous file with comments | « pkg/kernel/binary.md ('k') | pkg/kernel/lib/ast.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698