// property to the unresolved list.
_unresolvedPropertyList.add(node.getName());
return;
}
TypeInfo type = getCurrentTypeInfo();
TypeInfo fieldType = getFieldTypeInfo(node, type, name);
if (fieldType != null) {
// This property is a known field type for the class.
addSemanticRecordToNode(node, fieldType,
getPropertyInfo(type, name),
Symbol.Field,
getFullPath(node));
}
else if (ReservedVarNames.indexOf(name) != -1) {
// Reserved word such as "this" and "it" will be handled by
// ASTThis and ASTIt. If these symbols are encountered here,
// they are embedded within the property chain.
addError(node, Fmt.S("%s %s",
"Fail to find field '%s' in type '%s'.",
"Field '%s' is a reserved word which should be used at the beginning of a field path."));
}
else if (isFirstInPropertyChain(node) &&
(type = getTypeInfo(node, name)) != null) {
// This symbol represents a type alias.
addSemanticRecordToNode(node, type, null, Symbol.Type, null);
}
else if (isVariableSymbol(node)) {
// This is a variable.
SemanticRecord record = getSemanticRecordForSymbol(
node.getName(), Symbol.Variable);
if (record != null && record.getSymbolKind() == Symbol.Variable) {
// It is a known variable. There is no scoping rule
// for variable. So for the symbol table, the latest type
// info of the variable takes over.
TypeInfo info = (record != null ? record.getTypeInfo() : null);
addSemanticRecordToNode(node, info, null, Symbol.Variable, null);
// If this varaible is associated with a constant value,
// then associate this node with that constant.
setNodeConstantValue(node, record.getNode());
}
}
else if (predecessorHasConstantValue(node)) {
// If the predecessor of this property is a map constant, then
// this property may specify the key to lookup the map element.
Node value = getValueFromConstantPredecessor(node);
TypeInfo info = getTypeInfoForNodeValue(value);
addSemanticRecordToNode(node, info, null, Symbol.Key, getFullPath(node));
setNodeConstantValue(node, value);
}
else if (isInPropertyChain(node)) {