} else {
argumentValues[i] = constantVisitor.valueOf(argument);
}
}
constructor = followConstantRedirectionChain(constructor);
InterfaceType definingClass = (InterfaceType) constructor.getReturnType();
if (constructor.isFactory()) {
// We couldn't find a non-factory constructor. See if it's because we reached an external
// const factory constructor that we can emulate.
if (constructor.getName().equals("fromEnvironment")) {
if (!checkFromEnvironmentArguments(
arguments,
argumentValues,
namedArgumentValues,
definingClass)) {
return new ErrorResult(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
String variableName = argumentCount < 1 ? null : argumentValues[0].getStringValue();
if (definingClass == typeProvider.getBoolType()) {
DartObject valueFromEnvironment;
valueFromEnvironment = declaredVariables.getBool(typeProvider, variableName);
return computeValueFromEnvironment(
valueFromEnvironment,
new DartObjectImpl(typeProvider.getBoolType(), BoolState.FALSE_STATE),
namedArgumentValues);
} else if (definingClass == typeProvider.getIntType()) {
DartObject valueFromEnvironment;
valueFromEnvironment = declaredVariables.getInt(typeProvider, variableName);
return computeValueFromEnvironment(
valueFromEnvironment,
new DartObjectImpl(typeProvider.getNullType(), NullState.NULL_STATE),
namedArgumentValues);
} else if (definingClass == typeProvider.getStringType()) {
DartObject valueFromEnvironment;
valueFromEnvironment = declaredVariables.getString(typeProvider, variableName);
return computeValueFromEnvironment(
valueFromEnvironment,
new DartObjectImpl(typeProvider.getNullType(), NullState.NULL_STATE),
namedArgumentValues);
}
} else if (constructor.getName().equals("") && definingClass == typeProvider.getSymbolType()
&& argumentCount == 1) {
if (!checkSymbolArguments(arguments, argumentValues, namedArgumentValues)) {
return new ErrorResult(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
String argumentValue = argumentValues[0].getStringValue();
return constantVisitor.valid(definingClass, new SymbolState(argumentValue));
}
// Either it's an external const factory constructor that we can't emulate, or an error
// occurred (a cycle, or a const constructor trying to delegate to a non-const constructor).
// In the former case, the best we can do is consider it an unknown value. In the latter
// case, the error has already been reported, so considering it an unknown value will
// suppress further errors.
return constantVisitor.validWithUnknownValue(definingClass);
}
beforeGetConstantInitializers(constructor);
ConstructorElementImpl constructorBase = (ConstructorElementImpl) getConstructorBase(constructor);
List<ConstructorInitializer> initializers = constructorBase.getConstantInitializers();
if (initializers == null) {
// This can happen in some cases where there are compile errors in the code being analyzed
// (for example if the code is trying to create a const instance using a non-const
// constructor, or the node we're visiting is involved in a cycle). The error has already
// been reported, so consider it an unknown value to suppress further errors.
return constantVisitor.validWithUnknownValue(definingClass);
}
HashMap<String, DartObjectImpl> fieldMap = new HashMap<String, DartObjectImpl>();
HashMap<String, DartObjectImpl> parameterMap = new HashMap<String, DartObjectImpl>();
ParameterElement[] parameters = constructorBase.getParameters();
int parameterCount = parameters.length;
for (int i = 0; i < parameterCount; i++) {
ParameterElement parameter = parameters[i];
while (parameter instanceof ParameterMember) {
parameter = ((ParameterMember) parameter).getBaseElement();
}
DartObjectImpl argumentValue = null;
if (parameter.getParameterKind() == ParameterKind.NAMED) {
argumentValue = namedArgumentValues.get(parameter.getName());
} else if (i < argumentCount) {
argumentValue = argumentValues[i];
}
if (argumentValue == null && parameter instanceof ParameterElementImpl) {
// The parameter is an optional positional parameter for which no value was provided, so
// use the default value.
beforeGetParameterDefault(parameter);
EvaluationResultImpl evaluationResult = ((ParameterElementImpl) parameter).getEvaluationResult();
if (evaluationResult instanceof ValidResult) {
argumentValue = ((ValidResult) evaluationResult).getValue();
} else if (evaluationResult == null) {
// No default was provided, so the default value is null.
argumentValue = constantVisitor.getNull();
}
}
if (argumentValue != null) {
if (parameter.isInitializingFormal()) {
FieldElement field = ((FieldFormalParameterElement) parameter).getField();
if (field != null) {
String fieldName = field.getName();
fieldMap.put(fieldName, argumentValue);
}
} else {
String name = parameter.getName();
parameterMap.put(name, argumentValue);
}
}
}
ConstantVisitor initializerVisitor = new ConstantVisitor(typeProvider, parameterMap);
String superName = null;
NodeList<Expression> superArguments = null;
for (ConstructorInitializer initializer : initializers) {
if (initializer instanceof ConstructorFieldInitializer) {
ConstructorFieldInitializer constructorFieldInitializer = (ConstructorFieldInitializer) initializer;
Expression initializerExpression = constructorFieldInitializer.getExpression();
EvaluationResultImpl evaluationResult = initializerExpression.accept(initializerVisitor);
if (evaluationResult instanceof ValidResult) {
DartObjectImpl value = ((ValidResult) evaluationResult).getValue();
String fieldName = constructorFieldInitializer.getFieldName().getName();
fieldMap.put(fieldName, value);
}
} else if (initializer instanceof SuperConstructorInvocation) {
SuperConstructorInvocation superConstructorInvocation = (SuperConstructorInvocation) initializer;
SimpleIdentifier name = superConstructorInvocation.getConstructorName();
if (name != null) {
superName = name.getName();
}
superArguments = superConstructorInvocation.getArgumentList().getArguments();
}
}
// Evaluate explicit or implicit call to super().
InterfaceType superclass = definingClass.getSuperclass();
if (superclass != null && !superclass.isObject()) {
ConstructorElement superConstructor = superclass.lookUpConstructor(
superName,
constructor.getLibrary());
if (superConstructor != null) {
if (superArguments == null) {
superArguments = new NodeList<Expression>(null);