It is a compile-time error for a constant value to depend on a
non-constant value (or a non-constant constructor), however the
analyzer still needs to be able to handle it.
This CL adjusts the ConstantEvaluationEngine so that it consistently
reports all the dependencies of a given constant (whether those
dependencies are constant are not), but which is tolerant of being
asked to compute a constant value of a non-constant.
Fixes test failures with the new task model enabled. No behavioral
change with the new task model disabled.
R=brianwilkerson@google.com
Review URL: https://codereview.chromium.org//1167413005.
If 'p' is an import prefix, then 'p = ...' is treated as synonymous
with 'this.p = ...', and 'p()' is treated as synonymous with
'this.p()'. In all other circumstances where 'p' is not followed by
'.', the spec calls for a compile time error.
Previous to this CL, 'p' not followed by '.' was being treated as
synonymous with 'this.p' under all circumstances. This CL brings
analyzer in line with the spec, and updates the tests in
tests/language accordingly.
The VM and Dart2js currently fail to implement the compile-time error
properly. See issues #23611 and #23612.
Fixes issue #23461.
R=scheglov@google.com
Review URL: https://codereview.chromium.org//1173523002.
If a constant constructor does not contain an explicit call to
super(), and the base class lacks an explicit constructor, we need to
avoid marking the implicit base class constructor as a dependency,
since it is non-const. (Note: this shouldn't occur very often in
real-world usage since is a compile-time error, but we still need to
be able to analyze it without throwing an exception).
Fixes the following test when the new task model is switched on:
co19/Language/07_Classes/6_Constructors/3_Constant_Constructors_A03_t02
R=brianwilkerson@google.com
Review URL: https://codereview.chromium.org//1168563004
It's not the main problem we observe during pkg/analysis_server/test/operation/operation_test, but I still saw it.
The actual fix is removing "unary-".
The other change is just for performance.
It is much cheaper to compare int(s) than to compute (for methods) 'displayName'.
Maybe we should go as far as removing the name check altogether and use just element kind.
R=brianwilkerson@google.com
BUG=
Review URL: https://codereview.chromium.org//1149083007
Modifier.TYPEDEF was redundant with Modifier.MIXIN_APPLICATION and
ClassElement.isTypedef was redundant with
ClassElement.isMixinApplication.
Since Modifier.TYPEDEF was private to analyzer, it has been
eliminated. Since ClassElement.isTypedef is part of the public API to
analyzer, it is retained, but with a "@deprecated" annotation.
R=scheglov@google.com
Review URL: https://codereview.chromium.org//1158193008
This is a re-fix of dartbug.com/21912, which I previously fixed
incorrectly. Previously, our approach to avoiding infinite loops when
comparing types was to maintain a set of typedefs being expanded on
the stack, and prune the comparison whenever an attempt was made to
expand a typedef that was already being expanded. However, this was
too strict, since there are legal (non-circular) types which invole
expanding a given typedef in reentrant fashion; we can't prune these
types without producing incorrect semantics. An example (from the bug
report) is the type of f in the code below:
typedef T Function2<S, T>(S z);
Function2<Function2<A, B>, Function2<B, A>> f;
The solution is to maintain the list of typedefs being expanded inside
each FunctionTypeImpl object (and InterfaceTypeImpl object) rather
than on the stack during the comparison; this allows us to distinguish
the situations where we need to prune (those having to do exclusively
with expansion of a typedef) from the situations where we shouldn't
prune (those having to do with substitution of a type parameter).
A beneficial side effect of this change is that code that interacts
with types no longer needs to worry about typedef circularities, since
the circularities will automatically be pruned while exploring the
type definitions. This simplifies the implementation of
isAssignableTo, isSubtypeOf, operator==, and hashCode. (Note,
however, that code still needs to cope with circularities in the
inheritance hierarchy).
BUG=dartbug.com/21912
R=brianwilkerson@google.com
Review URL: https://codereview.chromium.org//1143003007
It is on the couple critical paths:
1. getErrors()
2. SearchEngine.
The SearchEngine is used in both search itself and by completion.
Without this change search has n^2 complexity, where `n` is the number of targets.
Statistics for search shows more than 10x performance improvement.
Before: 70 ms (analyzer), 230 ms (analyzer + dart2js).
After: 6 ms (analyzer), 17 ms (analyzer + dart2js).
R=brianwilkerson@google.com
BUG=
Review URL: https://codereview.chromium.org//1152773002
This is not ideal, we might still want to start managing 'containingLibraries' at some point.
But it speeds up switching between file 10x - DartCompletionCache request of all top-level elements takes now about 170 ms, vs. 1800 ms before.
Also, we need "sources" in many places of AnalysisContext.
R=brianwilkerson@google.com
BUG=
Review URL: https://codereview.chromium.org//1149893004
We need to be more careful about this in the new task model, since the
new task model is more aggressive about chasing dependencies, and we
don't want constant evaluation to try to visit a non-const
constructor.
R=scheglov@google.com
Review URL: https://codereview.chromium.org//1145913002