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

Unified Diff: pkg/analyzer/lib/src/summary/fasta/expressions.dart

Issue 2738273002: Add fasta-based summary generation code. (Closed)
Patch Set: Actually disable the test 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/summary/fasta/expressions.dart
diff --git a/pkg/analyzer/lib/src/summary/fasta/expressions.dart b/pkg/analyzer/lib/src/summary/fasta/expressions.dart
new file mode 100644
index 0000000000000000000000000000000000000000..81b9e503c27b6994b72458a2f5ceaacd095f91e5
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/fasta/expressions.dart
@@ -0,0 +1,306 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Minimal AST used to represent constant and initializer expressions.
+///
+/// The AST definitions here are kept small by removing anything that we don't
+/// need for the purpose of summarization:
+///
+/// * A tree representing constants will not contain nodes that are not
+/// allowed. If a parsed program contains a subexpression that is invalid,
+/// we'll represent it with an `Invalid` node.
+///
+/// * A tree representing initializers will only contain the subset of the
+/// initializer expression that is needed to infer the type of the initialized
+/// variable. For example, function closures, arguments to constructors, and
+/// other similar bits are hidden using `Opaque` nodes.
+library summary.src.expressions;
+
+// We reuse the scanner constants to represent all binary and unary operators.
+import 'visitor.dart';
+export 'visitor.dart';
+
+/// A reference to a type (used for opaque nodes, is checks, and as checks).
+///
+/// Note that types are not nodes in the expression tree.
+class TypeRef {
+ final Ref name;
+ final List<TypeRef> typeArguments;
+ TypeRef(this.name, this.typeArguments);
+
+ toString() {
+ var args = typeArguments == null ? "" : "<${typeArguments.join(', ')}>";
+ return 't:$name$args';
+ }
+}
+
+/// Root of all expressions
+abstract class Expression {
+ bool get isRef => false;
+ bool get isBinary => false;
+ bool get isUnary => false;
+ bool get isConditional => false;
+ bool get isLoad => false;
+ bool get isIdentical => false;
+ bool get isAs => false;
+ bool get isIs => false;
+ bool get isOpaqueOp => false;
+
+ accept(Visitor v);
+}
+
+/// A name reference.
+class Ref extends Expression {
+ final String name;
+ final Ref prefix;
+
+ int get prefixDepth => prefix == null ? 0 : prefix.prefixDepth;
+
+ Ref(this.name, [this.prefix]) {
+ assert(prefixDepth <= 2);
+ }
+
+ toString() => 'r:${prefix == null ? "" : "$prefix."}$name';
+ bool get isRef => true;
+ accept(v) => v.visitRef(this);
+}
+
+/// A literal like `"foo"`.
+class StringLiteral extends Expression {
+ final String value;
+ StringLiteral(this.value);
+
+ toString() => '$value';
+ accept(v) => v.visitString(this);
+}
+
+/// A literal like `#foo.bar`.
+class SymbolLiteral extends Expression {
+ final String value;
+ SymbolLiteral(this.value);
+
+ accept(v) => v.visitSymbol(this);
+ toString() => '#$value';
+}
+
+/// A literal like `1`.
+class IntLiteral extends Expression {
+ final int value;
+ IntLiteral(this.value);
+
+ toString() => '$value';
+ accept(v) => v.visitInt(this);
+}
+
+/// A literal like `1.2`.
+class DoubleLiteral extends Expression {
+ final double value;
+ DoubleLiteral(this.value);
+
+ toString() => '$value';
+ accept(v) => v.visitDouble(this);
+}
+
+/// A literal like `false`.
+class BoolLiteral extends Expression {
+ final bool value;
+ BoolLiteral(this.value);
+
+ toString() => '$value';
+ accept(v) => v.visitBool(this);
+}
+
+/// The `null` literal.
+class NullLiteral extends Expression {
+ NullLiteral();
+
+ toString() => 'null';
+ accept(v) => v.visitNull(this);
+}
+
+/// A list literal like: `[1, 2]`.
+class ListLiteral extends Expression {
+ final TypeRef elementType;
+ final List<Expression> values;
+ final bool isConst;
+ ListLiteral(this.elementType, this.values, this.isConst);
+
+ toString() => '(list<$elementType>$values)';
+ accept(v) => v.visitList(this);
+}
+
+/// An entry in a map literal.
+class KeyValuePair {
+ final Expression key;
+ final Expression value;
+ KeyValuePair(this.key, this.value);
+
+ toString() => '(p: $key, $value)';
+}
+
+/// A map literal like: `{'a': 2}`.
+class MapLiteral extends Expression {
+ final List<TypeRef> types;
+ final List<KeyValuePair> values;
+ final bool isConst;
+
+ MapLiteral(this.types, this.values, this.isConst) {
+ assert(types.length <= 2);
+ }
+
+ toString() => '(map<${types.map((t) => "$t").join(", ")}>: $values)';
+ accept(v) => v.visitMap(this);
+}
+
+/// Expressions like `a ? b : c`.
+class Conditional extends Expression {
+ final Expression test;
+ final Expression trueBranch;
+ final Expression falseBranch;
+ Conditional(this.test, this.trueBranch, this.falseBranch);
+
+ bool get isConditional => true;
+ toString() => '$test ? $trueBranch : $falseBranch';
+ accept(v) => v.visitConditional(this);
+}
+
+/// All binary expressions, including if-null.
+class Binary extends Expression {
+ final Expression left;
+ final Expression right;
+ final int operator;
+ Binary(this.left, this.right, this.operator);
+
+ bool get isBinary => true;
+ toString() => '$left _ $right';
+ accept(v) => v.visitBinary(this);
+}
+
+/// An identical expression: `identical(a, b)`.
+// TODO(sigmund): consider merging it into binary?
+class Identical extends Expression {
+ final Expression left;
+ final Expression right;
+ Identical(this.left, this.right);
+
+ bool get isIdentical => true;
+ toString() => 'identical($left, $right)';
+ accept(v) => v.visitIdentical(this);
+}
+
+/// A property extraction expression, such as: `(e).foo`
+// TODO(sigmund): consider merging it into binary?
+class Load extends Expression {
+ final Expression left;
+ final String name;
+ Load(this.left, this.name);
+
+ bool get isLoad => true;
+ toString() => '$left.$name';
+ accept(v) => v.visitLoad(this);
+}
+
+/// All unary expressions, such as `-1` or `!b`
+class Unary extends Expression {
+ final Expression exp;
+ final int operator;
+ Unary(this.exp, this.operator);
+
+ bool get isUnary => true;
+ toString() => '_ $exp';
+ accept(v) => v.visitUnary(this);
+}
+
+/// A cast expression.
+class As extends Expression {
+ final Expression exp;
+ final TypeRef type;
+ As(this.exp, this.type);
+
+ bool get isAs => true;
+ accept(v) => v.visitAs(this);
+ toString() => '$exp as $type';
+}
+
+/// An instance check expression.
+class Is extends Expression {
+ final Expression exp;
+ final TypeRef type;
+ Is(this.exp, this.type);
+
+ bool get isIs => true;
+ accept(v) => v.visitIs(this);
+ toString() => '$exp is $type';
+}
+
+/// An erroneous expression, typically encapsulates code that is not expected
+/// in a constant context.
+class Invalid extends Expression {
+ String hint;
+ Invalid({this.hint});
+ accept(v) => v.visitInvalid(this);
+
+ toString() => '(err: $hint)';
+}
+
+/// Representation for a named argument.
+class NamedArg {
+ final String name;
+ final Expression value;
+ NamedArg(this.name, this.value);
+}
+
+/// The type and possibly name of a constructor.
+class ConstructorName {
+ final TypeRef type;
+ final String name;
+ ConstructorName(this.type, this.name);
+
+ toString() => "ctor: $type.$name";
+}
+
+/// A `const Foo()` creation.
+class ConstCreation extends Expression {
+ final ConstructorName constructor;
+
+ /// Passed arguments, which can be expressions (if the argument is positional)
+ /// or a [NamedArg].
+ final List<Expression> positionalArgs;
+ final List<NamedArg> namedArgs;
+ ConstCreation(this.constructor, this.positionalArgs, this.namedArgs);
+
+ accept(v) => v.visitConstCreation(this);
+}
+
+/// An opaque expression with possibly a known type.
+class Opaque extends Expression {
+ final TypeRef type;
+ final String hint;
+
+ Opaque({this.type, this.hint});
+
+ toString() {
+ var sb = new StringBuffer();
+ sb.write('(o:');
+ if (hint != null) sb.write(' $hint');
+ if (type != null) sb.write(' $type');
+ return '$sb)';
+ }
+ accept(v) => v.visitOpaque(this);
+}
+
+/// Marker that some part of the AST was abstracted away.
+///
+/// This node does not provide additional information, other than indicating
+/// that the AST does not include the full initializer. For example,
+/// this is in assignments, pre and postfix operators, and cascades to indicate
+/// that we ignored part of those complex expressions.
+class OpaqueOp extends Expression {
+ final Expression exp;
+ final String hint;
+ OpaqueOp(this.exp, {this.hint});
+
+ bool get isOpaqueOp => true;
+ accept(v) => v.visitOpaqueOp(this);
+}

Powered by Google App Engine
This is Rietveld 408576698