}
//
// If not, the look to see whether we might have created the wrong AST structure for a
// constructor name. If so, fix the AST structure and then proceed.
//
AstNode parent = node.getParent();
if (typeName instanceof PrefixedIdentifier && parent instanceof ConstructorName
&& argumentList == null) {
ConstructorName name = (ConstructorName) parent;
if (name.getName() == null) {
PrefixedIdentifier prefixedIdentifier = (PrefixedIdentifier) typeName;
SimpleIdentifier prefix = prefixedIdentifier.getPrefix();
element = getNameScope().lookup(prefix, getDefiningLibrary());
if (element instanceof PrefixElement) {
if (parent.getParent() instanceof InstanceCreationExpression
&& ((InstanceCreationExpression) parent.getParent()).isConst()) {
// If, if this is a const expression, then generate a
// CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
reportErrorForNode(
CompileTimeErrorCode.CONST_WITH_NON_TYPE,
prefixedIdentifier.getIdentifier(),
prefixedIdentifier.getIdentifier().getName());
} else {
// Else, if this expression is a new expression, report a NEW_WITH_NON_TYPE warning.
reportErrorForNode(
StaticWarningCode.NEW_WITH_NON_TYPE,
prefixedIdentifier.getIdentifier(),
prefixedIdentifier.getIdentifier().getName());
}
setElement(prefix, element);
return null;
} else if (element != null) {
//
// Rewrite the constructor name. The parser, when it sees a constructor named "a.b",
// cannot tell whether "a" is a prefix and "b" is a class name, or whether "a" is a
// class name and "b" is a constructor name. It arbitrarily chooses the former, but
// in this case was wrong.
//
name.setName(prefixedIdentifier.getIdentifier());
name.setPeriod(prefixedIdentifier.getPeriod());
node.setName(prefix);
typeName = prefix;
}
}
}
}
// check element
boolean elementValid = !(element instanceof MultiplyDefinedElement);
if (elementValid && !(element instanceof ClassElement)
&& isTypeNameInInstanceCreationExpression(node)) {
SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
InstanceCreationExpression creation = (InstanceCreationExpression) node.getParent().getParent();
if (creation.isConst()) {
if (element == null) {
reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, typeName);
} else {
reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple, typeName);
}
elementValid = false;
} else {
if (element != null) {
reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, typeName);
elementValid = false;
}
}
}
if (elementValid && element == null) {
// We couldn't resolve the type name.
// TODO(jwren) Consider moving the check for CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE
// from the ErrorVerifier, so that we don't have two errors on a built in identifier being
// used as a class name. See CompileTimeErrorCodeTest.test_builtInIdentifierAsType().
SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
RedirectingConstructorKind redirectingConstructorKind;
if (isBuiltInIdentifier(node) && isTypeAnnotation(node)) {
reportErrorForNode(
CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
typeName,
typeName.getName());
} else if (typeNameSimple.getName().equals("boolean")) {
reportErrorForNode(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple);
} else if (isTypeNameInCatchClause(node)) {
reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, typeName.getName());
} else if (isTypeNameInAsExpression(node)) {
reportErrorForNode(StaticWarningCode.CAST_TO_NON_TYPE, typeName, typeName.getName());
} else if (isTypeNameInIsExpression(node)) {
reportErrorForNode(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, typeName.getName());
} else if ((redirectingConstructorKind = getRedirectingConstructorKind(node)) != null) {
ErrorCode errorCode = redirectingConstructorKind == RedirectingConstructorKind.CONST
? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarningCode.REDIRECT_TO_NON_CLASS;
reportErrorForNode(errorCode, typeName, typeName.getName());
} else if (isTypeNameInTypeArgumentList(node)) {
reportErrorForNode(
StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
typeName,
typeName.getName());
} else {
reportErrorForNode(StaticWarningCode.UNDEFINED_CLASS, typeName, typeName.getName());
}
elementValid = false;
}
if (!elementValid) {
if (element instanceof MultiplyDefinedElement) {
setElement(typeName, element);
} else {
setElement(typeName, dynamicType.getElement());
}
typeName.setStaticType(dynamicType);
node.setType(dynamicType);
return null;
}
Type type = null;
if (element instanceof ClassElement) {
setElement(typeName, element);
type = ((ClassElement) element).getType();
} else if (element instanceof FunctionTypeAliasElement) {
setElement(typeName, element);
type = ((FunctionTypeAliasElement) element).getType();
} else if (element instanceof TypeParameterElement) {
setElement(typeName, element);
type = ((TypeParameterElement) element).getType();
if (argumentList != null) {
// Type parameters cannot have type arguments.
// TODO(brianwilkerson) Report this error.
// resolver.reportError(ResolverErrorCode.?, keyType);
}
} else if (element instanceof MultiplyDefinedElement) {
Element[] elements = ((MultiplyDefinedElement) element).getConflictingElements();
type = getTypeWhenMultiplyDefined(elements);
if (type != null) {
node.setType(type);
}
} else {
// The name does not represent a type.
RedirectingConstructorKind redirectingConstructorKind;
if (isTypeNameInCatchClause(node)) {
reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, typeName.getName());
} else if (isTypeNameInAsExpression(node)) {
reportErrorForNode(StaticWarningCode.CAST_TO_NON_TYPE, typeName, typeName.getName());
} else if (isTypeNameInIsExpression(node)) {
reportErrorForNode(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, typeName.getName());
} else if ((redirectingConstructorKind = getRedirectingConstructorKind(node)) != null) {
ErrorCode errorCode = redirectingConstructorKind == RedirectingConstructorKind.CONST
? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarningCode.REDIRECT_TO_NON_CLASS;
reportErrorForNode(errorCode, typeName, typeName.getName());
} else if (isTypeNameInTypeArgumentList(node)) {
reportErrorForNode(
StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
typeName,
typeName.getName());
} else {
AstNode parent = typeName.getParent();
while (parent instanceof TypeName) {
parent = parent.getParent();
}
if (parent instanceof ExtendsClause || parent instanceof ImplementsClause
|| parent instanceof WithClause || parent instanceof ClassTypeAlias) {
// Ignored. The error will be reported elsewhere.
} else {