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

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 137143010: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b6edb9539102dc300e09d9ac2220992865aa3225..366162f80da4c37e73733933535bc0aaee848ea0 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -49,16 +49,6 @@ class AngularCompilationUnitBuilder {
static String _CSS_URL = "cssUrl";
- static String _PREFIX_ATTR = "@";
-
- static String _PREFIX_CALLBACK = "&";
-
- static String _PREFIX_ONE_WAY = "=>";
-
- static String _PREFIX_ONE_WAY_ONE_TIME = "=>!";
-
- static String _PREFIX_TWO_WAY = "<=>";
-
static String _NG_ATTR = "NgAttr";
static String _NG_CALLBACK = "NgCallback";
@@ -69,9 +59,34 @@ class AngularCompilationUnitBuilder {
static String _NG_TWO_WAY = "NgTwoWay";
+ /**
+ * Returns the array of all top-level Angular elements that could be used in this library.
+ *
+ * @param libraryElement the [LibraryElement] to analyze
+ * @return the array of all top-level Angular elements that could be used in this library
+ */
+ static List<AngularElement> getAngularElements(LibraryElement libraryElement) {
+ List<AngularElement> angularElements = [];
+ // add Angular elements from current library
+ for (CompilationUnitElement unit in libraryElement.units) {
+ for (ClassElement type in unit.types) {
+ addAngularElements(angularElements, type);
+ }
+ }
+ // handle imports
+ for (ImportElement importElement in libraryElement.imports) {
+ Namespace namespace = new NamespaceBuilder().createImportNamespace(importElement);
+ for (Element importedElement in namespace.definedNames.values) {
+ addAngularElements(angularElements, importedElement);
+ }
+ }
+ // done
+ return new List.from(angularElements);
+ }
+
static Element getElement(ASTNode node, int offset) {
- // maybe no node
- if (node == null) {
+ // maybe node is not SimpleStringLiteral
+ if (node is! SimpleStringLiteral) {
return null;
}
// prepare enclosing ClassDeclaration
@@ -87,9 +102,23 @@ class AngularCompilationUnitBuilder {
// check toolkit objects
for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) {
List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARRAY;
+ // maybe name
+ if (toolkitObject is AngularElement) {
+ if (isNameCoveredByLiteral(toolkitObject, node)) {
+ return toolkitObject;
+ }
+ }
// try properties of AngularComponentElement
if (toolkitObject is AngularComponentElement) {
AngularComponentElement component = toolkitObject;
+ // try selector
+ {
+ AngularSelectorElement selector = component.selector;
+ if (isNameCoveredByLiteral(selector, node)) {
+ return selector;
+ }
+ }
+ // try properties
properties = component.properties;
}
// try properties of AngularDirectiveElement
@@ -100,9 +129,7 @@ class AngularCompilationUnitBuilder {
// check properties
for (AngularPropertyElement property in properties) {
// property name (use complete node range)
- int propertyOffset = property.nameOffset;
- int propertyEnd = propertyOffset + property.name.length;
- if (node.offset <= propertyOffset && propertyEnd < node.end) {
+ if (isNameCoveredByLiteral(property, node)) {
return property;
}
// field name (use complete node range, including @, => and <=>)
@@ -121,37 +148,11 @@ class AngularCompilationUnitBuilder {
}
/**
- * Checks if given [Type] is an Angular <code>Module</code> or its subclass.
- */
- static bool isModule(Type2 type) {
- if (type is! InterfaceType) {
- return false;
- }
- InterfaceType interfaceType = type as InterfaceType;
- // check hierarchy
- Set<Type2> seenTypes = new Set();
- while (interfaceType != null) {
- // check for recursion
- if (!seenTypes.add(interfaceType)) {
- return false;
- }
- // check for "Module"
- if (interfaceType.element.name == "Module") {
- return true;
- }
- // try supertype
- interfaceType = interfaceType.superclass;
- }
- // no
- return false;
- }
-
- /**
* Parses given selector text and returns [AngularSelectorElement]. May be `null` if
* cannot parse.
*/
static AngularSelectorElement parseSelector(int offset, String text) {
- if (text.startsWith("[") && text.endsWith("]")) {
+ if (StringUtilities.startsWithChar(text, 0x5B) && StringUtilities.endsWithChar(text, 0x5D)) {
int nameOffset = offset + "[".length;
String attributeName = text.substring(1, text.length - 1);
// TODO(scheglov) report warning if there are spaces between [ and identifier
@@ -164,6 +165,24 @@ class AngularCompilationUnitBuilder {
}
/**
+ * Adds [AngularElement] declared by the given top-level [Element].
+ *
+ * @param angularElements the list to fill with top-level [AngularElement]s
+ * @param unitMember the top-level member of unit, such as [ClassElement], to get
+ * [AngularElement]s from
+ */
+ static void addAngularElements(List<AngularElement> angularElements, Element unitMember) {
+ if (unitMember is ClassElement) {
+ ClassElement type = unitMember;
+ for (ToolkitObjectElement toolkitObject in type.toolkitObjects) {
+ if (toolkitObject is AngularElement) {
+ angularElements.add(toolkitObject);
+ }
+ }
+ }
+ }
+
+ /**
* Returns the [FieldElement] of the first field in the given [FieldDeclaration].
*/
static FieldElement getOnlyFieldElement(FieldDeclaration fieldDeclaration) {
@@ -191,11 +210,19 @@ class AngularCompilationUnitBuilder {
}
/**
- * Checks if given [LocalVariableElement] is an Angular <code>Module</code>.
+ * Checks if the name range of the given [Element] is completely covered by the given
+ * [SimpleStringLiteral].
*/
- static bool isModule2(VariableDeclaration node) {
- Type2 type = node.name.bestType;
- return isModule(type);
+ static bool isNameCoveredByLiteral(Element element, ASTNode node) {
+ if (element != null) {
+ String name = element.name;
+ if (name != null) {
+ int nameOffset = element.nameOffset;
+ int nameEnd = nameOffset + name.length;
+ return node.offset <= nameOffset && nameEnd < node.end;
+ }
+ }
+ return false;
}
/**
@@ -208,9 +235,9 @@ class AngularCompilationUnitBuilder {
}
/**
- * The source containing the unit that will be analyzed.
+ * The [AnalysisContext] that performs analysis.
*/
- Source _source;
+ AnalysisContext _context;
/**
* The listener to which errors will be reported.
@@ -218,6 +245,11 @@ class AngularCompilationUnitBuilder {
AnalysisErrorListener _errorListener;
/**
+ * The source containing the unit that will be analyzed.
+ */
+ Source _source;
+
+ /**
* The [ClassDeclaration] that is currently being analyzed.
*/
ClassDeclaration _classDeclaration;
@@ -243,7 +275,8 @@ class AngularCompilationUnitBuilder {
* @param errorListener the listener to which errors will be reported.
* @param source the source containing the unit that will be analyzed
*/
- AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source source) {
+ AngularCompilationUnitBuilder(AnalysisContext context, AnalysisErrorListener errorListener, Source source) {
+ this._context = context;
this._errorListener = errorListener;
this._source = source;
}
@@ -260,7 +293,6 @@ class AngularCompilationUnitBuilder {
this._classDeclaration = unitMember;
this._classElement = _classDeclaration.element as ClassElementImpl;
this._classToolkitObjects.clear();
- parseModuleClass();
// process annotations
NodeList<Annotation> annotations = _classDeclaration.metadata;
for (Annotation annotation in annotations) {
@@ -297,18 +329,6 @@ class AngularCompilationUnitBuilder {
}
}
}
- // process modules in variables
- parseModuleVariables(unit);
- }
-
- /**
- * Creates [AngularModuleElementImpl] for given information.
- */
- AngularModuleElementImpl createModuleElement(List<AngularModuleElement> childModules, List<ClassElement> keyTypes) {
- AngularModuleElementImpl module = new AngularModuleElementImpl();
- module.childModules = new List.from(childModules);
- module.keyTypes = new List.from(keyTypes);
- return module;
}
/**
@@ -375,73 +395,6 @@ class AngularCompilationUnitBuilder {
*/
bool isAngularAnnotation2(String name) => isAngularAnnotation(_annotation, name);
- /**
- * Checks if [classElement] is an Angular <code>Module</code>.
- */
- bool get isModule4 {
- InterfaceType supertype = _classElement.supertype;
- return isModule(supertype);
- }
-
- /**
- * Analyzes [classDeclaration] and if it is a module, creates [AngularModuleElement]
- * model for it.
- */
- void parseModuleClass() {
- if (!isModule4) {
- return;
- }
- // check install(), type() and value() invocations
- List<AngularModuleElement> childModules = [];
- List<ClassElement> keyTypes = [];
- _classDeclaration.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleClass(this, childModules, keyTypes));
- // set module element
- AngularModuleElementImpl module = createModuleElement(childModules, keyTypes);
- _classToolkitObjects.add(module);
- }
-
- /**
- * Checks if given [MethodInvocation] is an interesting <code>Module</code> method
- * invocation and remembers corresponding elements into lists.
- */
- void parseModuleInvocation(MethodInvocation node, List<AngularModuleElement> childModules, List<ClassElement> keyTypes) {
- String methodName = node.methodName.name;
- NodeList<Expression> arguments = node.argumentList.arguments;
- // install()
- if (arguments.length == 1 && methodName == "install") {
- Type2 argType = arguments[0].bestType;
- if (argType is InterfaceType) {
- ClassElement argElement = argType.element;
- List<ToolkitObjectElement> toolkitObjects = argElement.toolkitObjects;
- for (ToolkitObjectElement toolkitObject in toolkitObjects) {
- if (toolkitObject is AngularModuleElement) {
- childModules.add(toolkitObject);
- }
- }
- }
- return;
- }
- // type() and value()
- if (arguments.length >= 1 && (methodName == "type" || methodName == "value")) {
- Expression arg = arguments[0];
- if (arg is Identifier) {
- Element argElement = arg.staticElement;
- if (argElement is ClassElement) {
- keyTypes.add(argElement);
- }
- }
- return;
- }
- }
-
- /**
- * Checks every local variable in the given unit to see if it is a <code>Module</code> and creates
- * [AngularModuleElement] for it.
- */
- void parseModuleVariables(CompilationUnit unit) {
- unit.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables(this));
- }
-
void parseNgComponent() {
bool isValid = true;
// publishAs
@@ -484,6 +437,24 @@ class AngularCompilationUnitBuilder {
element.selector = selector;
element.templateUri = templateUri;
element.templateUriOffset = templateUriOffset;
+ // resolve template URI
+ // TODO(scheglov) resolve to HtmlElement to allow F3 ?
+ {
+ try {
+ parseUriWithException(templateUri);
+ // TODO(scheglov) think if there is better solution
+ if (templateUri.startsWith("packages/")) {
+ templateUri = "package:${templateUri.substring("packages/".length)}";
+ }
+ Source templateSource = _context.sourceFactory.resolveUri(_source, templateUri);
+ if (templateSource == null || !templateSource.exists()) {
+ reportErrorForArgument(_TEMPLATE_URL, AngularCode.URI_DOES_NOT_EXIST, [templateUri]);
+ }
+ element.templateSource = templateSource;
+ } on URISyntaxException catch (exception) {
+ reportErrorForArgument(_TEMPLATE_URL, AngularCode.INVALID_URI, [templateUri]);
+ }
+ }
element.styleUri = styleUri;
element.styleUriOffset = styleUriOffset;
element.properties = parseNgComponentProperties(true);
@@ -578,19 +549,19 @@ class AngularCompilationUnitBuilder {
// parse binding kind and field name
AngularPropertyKind kind;
int fieldNameOffset;
- if (spec.startsWith(_PREFIX_ATTR)) {
+ if (StringUtilities.startsWithChar(spec, 0x40)) {
kind = AngularPropertyKind.ATTR;
fieldNameOffset = 1;
- } else if (spec.startsWith(_PREFIX_CALLBACK)) {
+ } else if (StringUtilities.startsWithChar(spec, 0x26)) {
kind = AngularPropertyKind.CALLBACK;
fieldNameOffset = 1;
- } else if (spec.startsWith(_PREFIX_ONE_WAY_ONE_TIME)) {
+ } else if (StringUtilities.startsWith3(spec, 0, 0x3D, 0x3E, 0x21)) {
kind = AngularPropertyKind.ONE_WAY_ONE_TIME;
fieldNameOffset = 3;
- } else if (spec.startsWith(_PREFIX_ONE_WAY)) {
+ } else if (StringUtilities.startsWith2(spec, 0, 0x3D, 0x3E)) {
kind = AngularPropertyKind.ONE_WAY;
fieldNameOffset = 2;
- } else if (spec.startsWith(_PREFIX_TWO_WAY)) {
+ } else if (StringUtilities.startsWith3(spec, 0, 0x3C, 0x3D, 0x3E)) {
kind = AngularPropertyKind.TWO_WAY;
fieldNameOffset = 3;
} else {
@@ -704,84 +675,6 @@ class AngularCompilationUnitBuilder {
}
}
-class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleClass extends RecursiveASTVisitor<Object> {
- final AngularCompilationUnitBuilder AngularCompilationUnitBuilder_this;
-
- List<AngularModuleElement> childModules;
-
- List<ClassElement> keyTypes;
-
- RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleClass(this.AngularCompilationUnitBuilder_this, this.childModules, this.keyTypes) : super();
-
- Object visitMethodInvocation(MethodInvocation node) {
- if (node.target == null) {
- AngularCompilationUnitBuilder_this.parseModuleInvocation(node, childModules, keyTypes);
- }
- return null;
- }
-}
-
-class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables extends RecursiveASTVisitor<Object> {
- final AngularCompilationUnitBuilder AngularCompilationUnitBuilder_this;
-
- RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables(this.AngularCompilationUnitBuilder_this) : super();
-
- LocalVariableElementImpl _variable = null;
-
- Expression _variableInit = null;
-
- List<AngularModuleElement> _childModules = [];
-
- List<ClassElement> _keyTypes = [];
-
- Object visitClassDeclaration(ClassDeclaration node) => null;
-
- Object visitFunctionDeclaration(FunctionDeclaration node) {
- _childModules.clear();
- _keyTypes.clear();
- super.visitFunctionDeclaration(node);
- if (_variable != null) {
- AngularModuleElementImpl module = AngularCompilationUnitBuilder_this.createModuleElement(_childModules, _keyTypes);
- _variable.toolkitObjects = <ToolkitObjectElement> [module];
- }
- return null;
- }
-
- Object visitMethodInvocation(MethodInvocation node) {
- if (_variable != null) {
- if (isVariableInvocation(node)) {
- AngularCompilationUnitBuilder_this.parseModuleInvocation(node, _childModules, _keyTypes);
- }
- }
- return null;
- }
-
- Object visitVariableDeclaration(VariableDeclaration node) {
- VariableElement element = node.element;
- if (element is LocalVariableElementImpl && AngularCompilationUnitBuilder.isModule2(node)) {
- _variable = element;
- _variableInit = node.initializer;
- }
- return super.visitVariableDeclaration(node);
- }
-
- bool isVariableInvocation(MethodInvocation node) {
- Expression target = node.realTarget;
- // var module = new Module()..type(t1)..type(t2);
- if (_variableInit is CascadeExpression && target != null && identical(target.parent, _variableInit)) {
- return true;
- }
- // var module = new Module();
- // module.type(t);
- if (target is Identifier) {
- Element targetElement = target.staticElement;
- return identical(targetElement, _variable);
- }
- // no
- return false;
- }
-}
-
/**
* Instances of the class `CompilationUnitBuilder` build an element model for a single
* compilation unit.
@@ -2773,10 +2666,10 @@ class DeadCodeVerifier extends RecursiveASTVisitor<Object> {
if (currentType.isObject) {
// Found catch clause clause that has Object as an exception type, this is equivalent to
// having a catch clause that doesn't have an exception type, visit the block, but
- // generate an error on any following catch clauses (and don't visit them).
+ // generate an error on any following catch clauses (and don't visit them).
safelyVisit(catchClause);
if (i + 1 != numOfCatchClauses) {
- // this catch clause is not the last in the try statement
+ // this catch clause is not the last in the try statement
CatchClause nextCatchClause = catchClauses[i + 1];
CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
int offset = nextCatchClause.offset;
@@ -2798,7 +2691,7 @@ class DeadCodeVerifier extends RecursiveASTVisitor<Object> {
}
safelyVisit(catchClause);
} else {
- // Found catch clause clause that doesn't have an exception type, visit the block, but
+ // Found catch clause clause that doesn't have an exception type, visit the block, but
// generate an error on any following catch clauses (and don't visit them).
safelyVisit(catchClause);
if (i + 1 != numOfCatchClauses) {
@@ -2852,15 +2745,24 @@ class DeadCodeVerifier extends RecursiveASTVisitor<Object> {
}
// Don't consider situations where we could evaluate to a constant boolean expression with the
// ConstantVisitor
- // else {
- // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
- // if (result == ValidResult.RESULT_TRUE) {
- // return ValidResult.RESULT_TRUE;
- // } else if (result == ValidResult.RESULT_FALSE) {
- // return ValidResult.RESULT_FALSE;
- // }
- // return null;
- // }
+//
+ // else {
+//
+ // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+//
+ // if (result == ValidResult.RESULT_TRUE) {
+//
+ // return ValidResult.RESULT_TRUE;
+//
+ // } else if (result == ValidResult.RESULT_FALSE) {
+//
+ // return ValidResult.RESULT_FALSE;
+//
+ // }
+//
+ // return null;
+//
+ // }
return null;
}
@@ -2900,6 +2802,283 @@ class DeadCodeVerifier extends RecursiveASTVisitor<Object> {
}
/**
+ * Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed
+ * to terminate by executing a `return` statement, `throw` expression, `rethrow`
+ * expression, or simple infinite loop such as `while(true)`.
+ */
+class ExitDetector extends GeneralizingASTVisitor<bool> {
+ bool visitArgumentList(ArgumentList node) => visitExpressions(node.arguments);
+
+ bool visitAsExpression(AsExpression node) => node.expression.accept(this);
+
+ bool visitAssertStatement(AssertStatement node) => node.condition.accept(this);
+
+ bool visitAssignmentExpression(AssignmentExpression node) => node.leftHandSide.accept(this) || node.rightHandSide.accept(this);
+
+ bool visitBinaryExpression(BinaryExpression node) {
+ Expression lhsExpression = node.leftOperand;
+ sc.TokenType operatorType = node.operator.type;
+ // If the operator is || and the left hand side is false literal, don't consider the RHS of the
+ // binary expression.
+ // TODO(jwren) Do we want to take constant expressions into account, evaluate if(false) {}
+ // differently than if(<condition>), when <condition> evaluates to a constant false value?
+ if (identical(operatorType, sc.TokenType.BAR_BAR)) {
+ if (lhsExpression is BooleanLiteral) {
+ BooleanLiteral booleanLiteral = lhsExpression;
+ if (!booleanLiteral.value) {
+ return false;
+ }
+ }
+ }
+ // If the operator is && and the left hand side is true literal, don't consider the RHS of the
+ // binary expression.
+ if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) {
+ if (lhsExpression is BooleanLiteral) {
+ BooleanLiteral booleanLiteral = lhsExpression;
+ if (booleanLiteral.value) {
+ return false;
+ }
+ }
+ }
+ return lhsExpression.accept(this) || node.rightOperand.accept(this);
+ }
+
+ bool visitBlock(Block node) => visitStatements(node.statements);
+
+ bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this);
+
+ bool visitBreakStatement(BreakStatement node) => false;
+
+ bool visitCascadeExpression(CascadeExpression node) {
+ Expression target = node.target;
+ if (target.accept(this)) {
+ return true;
+ }
+ return visitExpressions(node.cascadeSections);
+ }
+
+ bool visitConditionalExpression(ConditionalExpression node) {
+ Expression conditionExpression = node.condition;
+ Expression thenStatement = node.thenExpression;
+ Expression elseStatement = node.elseExpression;
+ // TODO(jwren) Do we want to take constant expressions into account, evaluate if(false) {}
+ // differently than if(<condition>), when <condition> evaluates to a constant false value?
+ if (conditionExpression.accept(this)) {
+ return true;
+ }
+ if (thenStatement == null || elseStatement == null) {
+ return false;
+ }
+ return thenStatement.accept(this) && elseStatement.accept(this);
+ }
+
+ bool visitContinueStatement(ContinueStatement node) => false;
+
+ bool visitDoStatement(DoStatement node) {
+ Expression conditionExpression = node.condition;
+ if (conditionExpression.accept(this)) {
+ return true;
+ }
+ // TODO(jwren) Do we want to take all constant expressions into account?
+ if (conditionExpression is BooleanLiteral) {
+ BooleanLiteral booleanLiteral = conditionExpression;
+ if (booleanLiteral.value) {
+ return node.body.accept(this);
+ }
+ }
+ return false;
+ }
+
+ bool visitEmptyStatement(EmptyStatement node) => false;
+
+ bool visitExpressionStatement(ExpressionStatement node) => node.expression.accept(this);
+
+ bool visitForEachStatement(ForEachStatement node) => node.iterator.accept(this);
+
+ bool visitForStatement(ForStatement node) {
+ if (node.variables != null && visitVariableDeclarations(node.variables.variables)) {
+ return true;
+ }
+ if (node.initialization != null && node.initialization.accept(this)) {
+ return true;
+ }
+ if (node.condition != null && node.condition.accept(this)) {
+ return true;
+ }
+ return visitExpressions(node.updaters);
+ }
+
+ bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => false;
+
+ bool visitFunctionExpression(FunctionExpression node) => false;
+
+ bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ if (node.function.accept(this)) {
+ return true;
+ }
+ return node.argumentList.accept(this);
+ }
+
+ bool visitIdentifier(Identifier node) => false;
+
+ bool visitIfStatement(IfStatement node) {
+ Expression conditionExpression = node.condition;
+ Statement thenStatement = node.thenStatement;
+ Statement elseStatement = node.elseStatement;
+ // TODO(jwren) Do we want to take constant expressions into account, evaluate if(false) {}
+ // differently than if(<condition>), when <condition> evaluates to a constant false value?
+ if (conditionExpression.accept(this)) {
+ return true;
+ }
+ if (thenStatement == null || elseStatement == null) {
+ return false;
+ }
+ return thenStatement.accept(this) && elseStatement.accept(this);
+ }
+
+ bool visitIndexExpression(IndexExpression node) {
+ Expression target = node.target;
+ if (target != null && target.accept(this)) {
+ return true;
+ }
+ if (node.index.accept(this)) {
+ return true;
+ }
+ return false;
+ }
+
+ bool visitInstanceCreationExpression(InstanceCreationExpression node) => node.argumentList.accept(this);
+
+ bool visitIsExpression(IsExpression node) => node.expression.accept(this);
+
+ bool visitLabel(Label node) => false;
+
+ bool visitLabeledStatement(LabeledStatement node) => node.statement.accept(this);
+
+ bool visitLiteral(Literal node) => false;
+
+ bool visitMethodInvocation(MethodInvocation node) {
+ Expression target = node.target;
+ if (target != null && target.accept(this)) {
+ return true;
+ }
+ return node.argumentList.accept(this);
+ }
+
+ bool visitNamedExpression(NamedExpression node) => node.expression.accept(this);
+
+ bool visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this);
+
+ bool visitPostfixExpression(PostfixExpression node) => false;
+
+ bool visitPrefixExpression(PrefixExpression node) => false;
+
+ bool visitPropertyAccess(PropertyAccess node) => node.target.accept(this);
+
+ bool visitRethrowExpression(RethrowExpression node) => true;
+
+ bool visitReturnStatement(ReturnStatement node) => true;
+
+ bool visitSuperExpression(SuperExpression node) => false;
+
+ bool visitSwitchCase(SwitchCase node) => visitStatements(node.statements);
+
+ bool visitSwitchDefault(SwitchDefault node) => visitStatements(node.statements);
+
+ bool visitSwitchStatement(SwitchStatement node) {
+ bool hasDefault = false;
+ for (SwitchMember member in node.members) {
+ if (!member.accept(this)) {
+ return false;
+ }
+ if (member is SwitchDefault) {
+ hasDefault = true;
+ }
+ }
+ return hasDefault;
+ }
+
+ bool visitThisExpression(ThisExpression node) => false;
+
+ bool visitThrowExpression(ThrowExpression node) => true;
+
+ bool visitTryStatement(TryStatement node) {
+ if (node.body.accept(this)) {
+ return true;
+ }
+ Block finallyBlock = node.finallyBlock;
+ if (finallyBlock != null && finallyBlock.accept(this)) {
+ return true;
+ }
+ return false;
+ }
+
+ bool visitTypeName(TypeName node) => false;
+
+ bool visitVariableDeclaration(VariableDeclaration node) {
+ Expression initializer = node.initializer;
+ if (initializer != null) {
+ return initializer.accept(this);
+ }
+ return false;
+ }
+
+ bool visitVariableDeclarationList(VariableDeclarationList node) => visitVariableDeclarations(node.variables);
+
+ bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ NodeList<VariableDeclaration> variables = node.variables.variables;
+ for (int i = 0; i < variables.length; i++) {
+ if (variables[i].accept(this)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool visitWhileStatement(WhileStatement node) {
+ Expression conditionExpression = node.condition;
+ if (conditionExpression.accept(this)) {
+ return true;
+ }
+ // TODO(jwren) Do we want to take all constant expressions into account?
+ if (conditionExpression is BooleanLiteral) {
+ BooleanLiteral booleanLiteral = conditionExpression;
+ if (booleanLiteral.value) {
+ return node.body.accept(this);
+ }
+ }
+ return false;
+ }
+
+ bool visitExpressions(NodeList<Expression> expressions) {
+ for (int i = expressions.length - 1; i >= 0; i--) {
+ if (expressions[i].accept(this)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool visitStatements(NodeList<Statement> statements) {
+ for (int i = statements.length - 1; i >= 0; i--) {
+ if (statements[i].accept(this)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool visitVariableDeclarations(NodeList<VariableDeclaration> variableDeclarations) {
+ for (int i = variableDeclarations.length - 1; i >= 0; i--) {
+ if (variableDeclarations[i].accept(this)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/**
* Instances of the class `HintGenerator` traverse a library's worth of dart code at a time to
* generate hints over the set of sources.
*
@@ -3334,13 +3513,13 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
if (fullName != null) {
int pathIndex = 0;
int fullNameIndex = fullName.length;
- while (pathIndex < path.length && JavaString.startsWithBefore(path, "../", pathIndex)) {
+ while (pathIndex < path.length && StringUtilities.startsWith3(path, pathIndex, 0x2E, 0x2E, 0x2F)) {
fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex);
if (fullNameIndex < 4) {
return false;
}
// Check for "/lib" at a specified place in the fullName
- if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) {
+ if (StringUtilities.startsWith4(fullName, fullNameIndex - 4, 0x2F, 0x6C, 0x69, 0x62)) {
String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSPEC_YAML;
Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePubspecPath);
if (pubspecSource != null && pubspecSource.exists()) {
@@ -3366,17 +3545,17 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
* @see PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE
*/
bool checkForFileImportOutsideLibReferencesFileInside(StringLiteral uriLiteral, String path) {
- if (path.startsWith("lib/")) {
+ if (StringUtilities.startsWith4(path, 0, 0x6C, 0x69, 0x62, 0x2F)) {
if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, 0)) {
return true;
}
}
- int pathIndex = path.indexOf("/lib/");
+ int pathIndex = StringUtilities.indexOf5(path, 0, 0x2F, 0x6C, 0x69, 0x62, 0x2F);
while (pathIndex != -1) {
if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, pathIndex + 1)) {
return true;
}
- pathIndex = JavaString.indexOf(path, "/lib/", pathIndex + 4);
+ pathIndex = StringUtilities.indexOf5(path, pathIndex + 4, 0x2F, 0x6C, 0x69, 0x62, 0x2F);
}
return false;
}
@@ -3390,7 +3569,7 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
}
String fullName = getSourceFullName(source);
if (fullName != null) {
- if (!fullName.contains("/lib/")) {
+ if (StringUtilities.indexOf5(fullName, 0, 0x2F, 0x6C, 0x69, 0x62, 0x2F) < 0) {
// Files outside the lib directory hierarchy should not reference files inside
// ... use package: url instead
_errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, uriLiteral, []);
@@ -3409,7 +3588,7 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
* @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
*/
bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path) {
- if (path.startsWith("../") || path.contains("/../")) {
+ if (StringUtilities.startsWith3(path, 0, 0x2E, 0x2E, 0x2F) || StringUtilities.indexOf4(path, 0, 0x2F, 0x2E, 0x2E, 0x2F) >= 0) {
// Package import should not to contain ".."
_errorReporter.reportError3(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, uriLiteral, []);
return true;
@@ -3454,55 +3633,6 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
}
/**
- * Instances of the class `ReturnDetector` determine whether the visited AST node is
- * guaranteed (modulo exceptions) to terminate by executing a return statement.
- */
-class ReturnDetector extends UnifyingASTVisitor<bool> {
- bool visitBlock(Block node) => visitStatements(node.statements);
-
- bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this);
-
- bool visitIfStatement(IfStatement node) {
- Statement thenStatement = node.thenStatement;
- Statement elseStatement = node.elseStatement;
- if (thenStatement == null || elseStatement == null) {
- return false;
- }
- return thenStatement.accept(this) && elseStatement.accept(this);
- }
-
- bool visitNode(ASTNode node) => false;
-
- bool visitReturnStatement(ReturnStatement node) => true;
-
- bool visitSwitchCase(SwitchCase node) => visitStatements(node.statements);
-
- bool visitSwitchDefault(SwitchDefault node) => visitStatements(node.statements);
-
- bool visitSwitchStatement(SwitchStatement node) {
- bool hasDefault = false;
- for (SwitchMember member in node.members) {
- if (!member.accept(this)) {
- return false;
- }
- if (member is SwitchDefault) {
- hasDefault = true;
- }
- }
- return hasDefault;
- }
-
- bool visitStatements(NodeList<Statement> statements) {
- for (int i = statements.length - 1; i >= 0; i--) {
- if (statements[i].accept(this)) {
- return true;
- }
- }
- return false;
- }
-}
-
-/**
* Instances of the class `ToDoFinder` find to-do comments in Dart code.
*/
class ToDoFinder {
@@ -4950,7 +5080,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
SimpleIdentifier labelNode = node.label;
LabelElementImpl labelElement = lookupLabel(node, labelNode);
if (labelElement != null && labelElement.isOnSwitchMember) {
- _resolver.reportError7(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
+ _resolver.reportError8(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
}
return null;
}
@@ -5076,9 +5206,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
FieldElement fieldElement = enclosingClass.getField(fieldName.name);
fieldName.staticElement = fieldElement;
if (fieldElement == null || fieldElement.isSynthetic) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
} else if (fieldElement.isStatic) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
}
return null;
}
@@ -5116,7 +5246,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
SimpleIdentifier labelNode = node.label;
LabelElementImpl labelElement = lookupLabel(node, labelNode);
if (labelElement != null && labelElement.isOnSwitchStatement) {
- _resolver.reportError7(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
+ _resolver.reportError8(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
}
return null;
}
@@ -5144,7 +5274,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
if (classElement != null) {
FieldElement fieldElement = classElement.getField(fieldName);
if (fieldElement == null) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
} else {
ParameterElement parameterElement = node.element;
if (parameterElement is FieldFormalParameterElementImpl) {
@@ -5156,19 +5286,19 @@ class ElementResolver extends SimpleASTVisitor<Object> {
fieldFormal.type = fieldType;
}
if (fieldElement.isSynthetic) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
} else if (fieldElement.isStatic) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
} else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) {
// TODO(brianwilkerson) We should implement a displayName() method for types that will
// work nicely with function types and then use that below.
- _resolver.reportError7(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
+ _resolver.reportError8(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
}
} else {
if (fieldElement.isSynthetic) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
} else if (fieldElement.isStatic) {
- _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
+ _resolver.reportError8(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
}
}
}
@@ -5177,6 +5307,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
// // TODO(jwren) Report error, constructor initializer variable is a top level element
// // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCodes)
// }
+ setMetadata2(node.element, node);
return super.visitFieldFormalParameter(node);
}
@@ -5205,6 +5336,11 @@ class ElementResolver extends SimpleASTVisitor<Object> {
return null;
}
+ Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ setMetadata2(node.element, node);
+ return null;
+ }
+
Object visitImportDirective(ImportDirective node) {
SimpleIdentifier prefixNode = node.prefix;
if (prefixNode != null) {
@@ -5388,9 +5524,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
return null;
}
if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
- _resolver.reportError7(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
+ _resolver.reportError8(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
} else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) {
- _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
+ _resolver.reportError8(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
} else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
String targetTypeName;
if (target == null) {
@@ -5426,7 +5562,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
// The error code will never be generated via type propagation
Type2 targetType = getStaticType(target);
String targetTypeName = targetType == null ? null : targetType.name;
- _resolver.reportError7(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
+ _resolver.reportError8(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
}
return null;
}
@@ -5484,13 +5620,13 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
if (element == null) {
if (identifier.inSetterContext()) {
- _resolver.reportError7(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, prefixElement.name]);
+ _resolver.reportError8(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, prefixElement.name]);
} else if (node.parent is Annotation) {
Annotation annotation = node.parent as Annotation;
- _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
return null;
} else {
- _resolver.reportError7(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, prefixElement.name]);
+ _resolver.reportError8(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, prefixElement.name]);
}
return null;
}
@@ -5599,6 +5735,11 @@ class ElementResolver extends SimpleASTVisitor<Object> {
return null;
}
+ Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ setMetadata2(node.element, node);
+ return null;
+ }
+
Object visitSimpleIdentifier(SimpleIdentifier node) {
//
// Synthetic identifiers have been already reported during parsing.
@@ -5627,17 +5768,17 @@ class ElementResolver extends SimpleASTVisitor<Object> {
Element element = resolveSimpleIdentifier(node);
ClassElement enclosingClass = _resolver.enclosingClass;
if (isFactoryConstructorReturnType(node) && element != enclosingClass) {
- _resolver.reportError7(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
} else if (isConstructorReturnType(node) && element != enclosingClass) {
- _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
element = null;
} else if (element == null || (element is PrefixElement && !isValidAsPrefix(node))) {
// TODO(brianwilkerson) Recover from this error.
if (isConstructorReturnType(node)) {
- _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
} else if (node.parent is Annotation) {
Annotation annotation = node.parent as Annotation;
- _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
} else {
_resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
}
@@ -5674,14 +5815,14 @@ class ElementResolver extends SimpleASTVisitor<Object> {
ConstructorElement element = superType.lookUpConstructor(superName, _definingLibrary);
if (element == null) {
if (name != null) {
- _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
+ _resolver.reportError8(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
} else {
- _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
+ _resolver.reportError8(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
}
return null;
} else {
if (element.isFactory) {
- _resolver.reportError7(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
+ _resolver.reportError8(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
}
}
if (name != null) {
@@ -5698,7 +5839,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
Object visitSuperExpression(SuperExpression node) {
if (!isSuperInValidContext(node)) {
- _resolver.reportError7(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
+ _resolver.reportError8(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
}
return super.visitSuperExpression(node);
}
@@ -6261,11 +6402,11 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
} else {
if (labelScope == null) {
- _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
+ _resolver.reportError8(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
} else {
labelElement = labelScope.lookup(labelNode) as LabelElementImpl;
if (labelElement == null) {
- _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
+ _resolver.reportError8(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
} else {
labelNode.staticElement = labelElement;
}
@@ -6274,7 +6415,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
if (labelElement != null) {
ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElement);
if (labelContainer != _resolver.enclosingFunction) {
- _resolver.reportError7(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
+ _resolver.reportError8(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
labelElement = null;
}
}
@@ -6599,7 +6740,7 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
// we need constructor
if (constructor == null) {
- _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
return;
}
// record element
@@ -6611,13 +6752,13 @@ class ElementResolver extends SimpleASTVisitor<Object> {
void resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorElement accessorElement) {
// accessor should be synthetic
if (!accessorElement.isSynthetic) {
- _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
return;
}
// variable should be constant
VariableElement variableElement = accessorElement.variable;
if (!variableElement.isConst) {
- _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+ _resolver.reportError8(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
}
// OK
return;
@@ -6684,13 +6825,13 @@ class ElementResolver extends SimpleASTVisitor<Object> {
ParameterElement element = namedParameters[name];
if (element == null) {
ErrorCode errorCode = (reportError ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER) as ErrorCode;
- _resolver.reportError7(errorCode, nameNode, [name]);
+ _resolver.reportError8(errorCode, nameNode, [name]);
} else {
resolvedParameters[i] = element;
nameNode.staticElement = element;
}
if (!usedNames.add(name)) {
- _resolver.reportError7(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
+ _resolver.reportError8(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
}
} else {
positionalArgumentCount++;
@@ -6701,10 +6842,10 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
if (positionalArgumentCount < requiredParameters.length) {
ErrorCode errorCode = (reportError ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS) as ErrorCode;
- _resolver.reportError7(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
+ _resolver.reportError8(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
} else if (positionalArgumentCount > unnamedParameterCount) {
ErrorCode errorCode = (reportError ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS) as ErrorCode;
- _resolver.reportError7(errorCode, argumentList, [unnamedParameterCount, positionalArgumentCount]);
+ _resolver.reportError8(errorCode, argumentList, [unnamedParameterCount, positionalArgumentCount]);
}
return resolvedParameters;
}
@@ -7031,6 +7172,25 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
/**
+ * Given a node that can have annotations associated with it and the element to which that node
+ * has been resolved, create the annotations in the element model representing the annotations on
+ * the node.
+ *
+ * @param element the element to which the node has been resolved
+ * @param node the node that can have annotations associated with it
+ */
+ void setMetadata2(Element element, NormalFormalParameter node) {
+ if (element is! ElementImpl) {
+ return;
+ }
+ List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>();
+ addAnnotations(annotationList, node.metadata);
+ if (!annotationList.isEmpty) {
+ (element as ElementImpl).metadata = new List.from(annotationList);
+ }
+ }
+
+ /**
* Return `true` if we should report an error as a result of looking up a member in the
* given type and not finding any member.
*
@@ -7857,6 +8017,11 @@ class Library {
LibraryScope _libraryScope;
/**
+ * An array of all top-level Angular elements that could be used in this library.
+ */
+ List<AngularElement> angularElements;
+
+ /**
* An empty array that can be used to initialize lists of libraries.
*/
static List<Library> _EMPTY_ARRAY = new List<Library>(0);
@@ -8046,6 +8211,7 @@ class Library {
}
}
}
+ _libraryElement.hasExtUri2 = true;
return null;
}
try {
@@ -9006,8 +9172,11 @@ class LibraryResolver {
try {
for (Source source in library.compilationUnitSources) {
CompilationUnit ast = library.getAST(source);
- new AngularCompilationUnitBuilder(_errorListener, source).build(ast);
+ new AngularCompilationUnitBuilder(analysisContext, _errorListener, source).build(ast);
}
+ // remember accessible Angular elements
+ LibraryElementImpl libraryElement = library.libraryElement;
+ library.angularElements = AngularCompilationUnitBuilder.getAngularElements(libraryElement);
} finally {
timeCounter.stop();
}
@@ -10915,7 +11084,7 @@ abstract class ScopedVisitor extends UnifyingASTVisitor<Object> {
* @param node the node specifying the location of the error
* @param arguments the arguments to the error, used to compose the error message
*/
- void reportError7(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
+ void reportError8(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
_errorListener.onError(new AnalysisError.con2(source, node.offset, node.length, errorCode, arguments));
}
@@ -10927,7 +11096,7 @@ abstract class ScopedVisitor extends UnifyingASTVisitor<Object> {
* @param length the length of the location of the error
* @param arguments the arguments to the error, used to compose the error message
*/
- void reportError8(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
+ void reportError9(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
_errorListener.onError(new AnalysisError.con2(source, offset, length, errorCode, arguments));
}
@@ -10938,7 +11107,7 @@ abstract class ScopedVisitor extends UnifyingASTVisitor<Object> {
* @param token the token specifying the location of the error
* @param arguments the arguments to the error, used to compose the error message
*/
- void reportError9(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
+ void reportError10(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
_errorListener.onError(new AnalysisError.con2(source, token.offset, token.length, errorCode, arguments));
}
@@ -12426,17 +12595,17 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
// If the query has spaces, full parsing is required because it might be:
// E[text='warning text']
//
- if (argumentValue.contains(" ")) {
+ if (StringUtilities.indexOf1(argumentValue, 0, 0x20) >= 0) {
return null;
}
//
// Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/selector.html.
//
String tag = argumentValue;
- tag = StringUtilities.substringBefore(tag, ":");
- tag = StringUtilities.substringBefore(tag, "[");
- tag = StringUtilities.substringBefore(tag, ".");
- tag = StringUtilities.substringBefore(tag, "#");
+ tag = StringUtilities.substringBeforeChar(tag, 0x3A);
+ tag = StringUtilities.substringBeforeChar(tag, 0x5B);
+ tag = StringUtilities.substringBeforeChar(tag, 0x2E);
+ tag = StringUtilities.substringBeforeChar(tag, 0x23);
tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()];
ClassElement returnType = library.getType(tag);
if (returnType != null) {
@@ -13821,10 +13990,10 @@ class TypeResolverVisitor extends ScopedVisitor {
if (parent.parent is InstanceCreationExpression && (parent.parent as InstanceCreationExpression).isConst) {
// If, if this is a const expression, then generate a
// CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
- reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
+ reportError8(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
} else {
// Else, if this expression is a new expression, report a NEW_WITH_NON_TYPE warning.
- reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
+ reportError8(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
}
setElement(prefix, element);
return null;
@@ -13850,14 +14019,14 @@ class TypeResolverVisitor extends ScopedVisitor {
InstanceCreationExpression creation = node.parent.parent as InstanceCreationExpression;
if (creation.isConst) {
if (element == null) {
- reportError7(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
+ reportError8(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
} else {
- reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple, [typeName]);
+ reportError8(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple, [typeName]);
}
elementValid = false;
} else {
if (element != null) {
- reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
+ reportError8(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
elementValid = false;
}
}
@@ -13870,22 +14039,22 @@ class TypeResolverVisitor extends ScopedVisitor {
SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
RedirectingConstructorKind redirectingConstructorKind;
if (isBuiltInIdentifier(node) && isTypeAnnotation(node)) {
- reportError7(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typeName, [typeName.name]);
+ reportError8(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typeName, [typeName.name]);
} else if (typeNameSimple.name == "boolean") {
- reportError7(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
+ reportError8(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
} else if (isTypeNameInCatchClause(node)) {
- reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
} else if (isTypeNameInAsExpression(node)) {
- reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
} else if (isTypeNameInIsExpression(node)) {
- reportError7(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
} else if ((redirectingConstructorKind = getRedirectingConstructorKind(node)) != null) {
ErrorCode errorCode = (identical(redirectingConstructorKind, RedirectingConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarningCode.REDIRECT_TO_NON_CLASS) as ErrorCode;
- reportError7(errorCode, typeName, [typeName.name]);
+ reportError8(errorCode, typeName, [typeName.name]);
} else if (isTypeNameInTypeArgumentList(node)) {
- reportError7(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
+ reportError8(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
} else {
- reportError7(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
}
elementValid = false;
}
@@ -13921,16 +14090,16 @@ class TypeResolverVisitor extends ScopedVisitor {
// The name does not represent a type.
RedirectingConstructorKind redirectingConstructorKind;
if (isTypeNameInCatchClause(node)) {
- reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
} else if (isTypeNameInAsExpression(node)) {
- reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
} else if (isTypeNameInIsExpression(node)) {
- reportError7(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
} else if ((redirectingConstructorKind = getRedirectingConstructorKind(node)) != null) {
ErrorCode errorCode = (identical(redirectingConstructorKind, RedirectingConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarningCode.REDIRECT_TO_NON_CLASS) as ErrorCode;
- reportError7(errorCode, typeName, [typeName.name]);
+ reportError8(errorCode, typeName, [typeName.name]);
} else if (isTypeNameInTypeArgumentList(node)) {
- reportError7(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
+ reportError8(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
} else {
ASTNode parent = typeName.parent;
while (parent is TypeName) {
@@ -13938,7 +14107,7 @@ class TypeResolverVisitor extends ScopedVisitor {
}
if (parent is ExtendsClause || parent is ImplementsClause || parent is WithClause || parent is ClassTypeAlias) {
} else {
- reportError7(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
+ reportError8(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
}
}
setElement(typeName, this._dynamicType.element);
@@ -13960,7 +14129,7 @@ class TypeResolverVisitor extends ScopedVisitor {
}
}
if (argumentCount != parameterCount) {
- reportError7(getInvalidTypeParametersErrorCode(node), node, [typeName.name, parameterCount, argumentCount]);
+ reportError8(getInvalidTypeParametersErrorCode(node), node, [typeName.name, parameterCount, argumentCount]);
}
argumentCount = typeArguments.length;
if (argumentCount < parameterCount) {
@@ -14333,7 +14502,7 @@ class TypeResolverVisitor extends ScopedVisitor {
Element element2 = identifier2.staticElement;
if (element != null && element == element2) {
detectedRepeatOnIndex[j] = true;
- reportError7(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
+ reportError8(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
}
}
}
@@ -14358,9 +14527,9 @@ class TypeResolverVisitor extends ScopedVisitor {
// If the type is not an InterfaceType, then visitTypeName() sets the type to be a DynamicTypeImpl
Identifier name = typeName.name;
if (name.name == sc.Keyword.DYNAMIC.syntax) {
- reportError7(dynamicTypeError, name, [name.name]);
+ reportError8(dynamicTypeError, name, [name.name]);
} else {
- reportError7(nonTypeError, name, [name.name]);
+ reportError8(nonTypeError, name, [name.name]);
}
return null;
}
@@ -15375,7 +15544,7 @@ abstract class Scope {
/**
* The prefix used to mark an identifier as being private to its library.
*/
- static String PRIVATE_NAME_PREFIX = "_";
+ static int PRIVATE_NAME_PREFIX = 0x5F;
/**
* The suffix added to the declared name of a setter when looking up the setter. Used to
@@ -15395,7 +15564,7 @@ abstract class Scope {
* @param name the name being tested
* @return `true` if the given name is a library-private name
*/
- static bool isPrivateName(String name) => name != null && name.startsWith(PRIVATE_NAME_PREFIX);
+ static bool isPrivateName(String name) => name != null && StringUtilities.startsWithChar(name, PRIVATE_NAME_PREFIX);
/**
* A table mapping names that are defined in this scope to the element representing the thing
@@ -16124,6 +16293,12 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
bool _isInSystemLibrary = false;
/**
+ * A flag indicating whether the current library contains at least one import directive with a URI
+ * that uses the "dart-ext" scheme.
+ */
+ bool _hasExtUri = false;
+
+ /**
* The class containing the AST nodes being visited, or `null` if we are not in the scope of
* a class.
*/
@@ -16193,6 +16368,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
this._errorReporter = errorReporter;
this._currentLibrary = currentLibrary;
this._isInSystemLibrary = currentLibrary.source.isInSystemLibrary;
+ this._hasExtUri = currentLibrary.hasExtUri();
this._typeProvider = typeProvider;
this._inheritanceManager = inheritanceManager;
_isEnclosingConstructorConst = false;
@@ -19134,7 +19310,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
// Figure out the correct identifier to lookup in the inheritance graph, if 'x', then 'x=',
// or if 'x=', then 'x'.
String lookupIdentifier = propertyAccessorElement.name;
- if (lookupIdentifier.endsWith("=")) {
+ if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.length - 1);
} else {
lookupIdentifier += "=";
@@ -19278,8 +19454,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
* @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
*/
bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
- // TODO(brianwilkerson) Figure out the right rule for when 'native' is allowed.
- if (!_isInSystemLibrary) {
+ if (!_isInSystemLibrary && !_hasExtUri) {
_errorReporter.reportError3(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node, []);
return true;
}
@@ -19662,7 +19837,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
}
// name should start with '_'
SimpleIdentifier name = node.identifier;
- if (name.isSynthetic || !name.name.startsWith("_")) {
+ if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) {
return false;
}
// report problem
@@ -20848,7 +21023,7 @@ class ResolverErrorCode extends Enum<ResolverErrorCode> implements ErrorCode {
* The template used to create the correction to be displayed for this error, or `null` if
* there is no correction information for this error.
*/
- String correction10;
+ String correction9;
/**
* Initialize a newly created error code to have the given type and message.
@@ -20866,10 +21041,10 @@ class ResolverErrorCode extends Enum<ResolverErrorCode> implements ErrorCode {
* @param correction the template used to create the correction to be displayed for the error
*/
ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, String correction) : super(name, ordinal) {
- this.correction10 = correction;
+ this.correction9 = correction;
}
- String get correction => correction10;
+ String get correction => correction9;
ErrorSeverity get errorSeverity => type.severity;
}

Powered by Google App Engine
This is Rietveld 408576698