| 1150 | } |
| 1151 | |
| 1152 | int asCBuilder::VerifyProperty(asCDataType *dt, const char *decl, asCString &name, asCDataType &type, asSNameSpace *ns) |
| 1153 | { |
| 1154 | // Either datatype or namespace must be informed |
| 1155 | asASSERT( dt || ns ); |
| 1156 | |
| 1157 | Reset(); |
| 1158 | |
| 1159 | if( dt ) |
| 1160 | { |
| 1161 | // Verify that the object type exist |
| 1162 | if( CastToObjectType(dt->GetTypeInfo()) == 0 ) |
| 1163 | return asINVALID_OBJECT; |
| 1164 | } |
| 1165 | |
| 1166 | // Check property declaration and type |
| 1167 | asCScriptCode source; |
| 1168 | source.SetCode(TXT_PROPERTY, decl, true); |
| 1169 | |
| 1170 | asCParser parser(this); |
| 1171 | int r = parser.ParsePropertyDeclaration(&source); |
| 1172 | if( r < 0 ) |
| 1173 | return asINVALID_DECLARATION; |
| 1174 | |
| 1175 | // Get data type |
| 1176 | asCScriptNode *dataType = parser.GetScriptNode()->firstChild; |
| 1177 | |
| 1178 | // Check if the property is declared 'by reference' |
| 1179 | bool isReference = (dataType->next->tokenType == ttAmp); |
| 1180 | |
| 1181 | // Get the name of the property |
| 1182 | asCScriptNode *nameNode = isReference ? dataType->next->next : dataType->next; |
| 1183 | |
| 1184 | // If an object property is registered, then use the |
| 1185 | // object's namespace, otherwise use the specified namespace |
| 1186 | type = CreateDataTypeFromNode(dataType, &source, dt ? dt->GetTypeInfo()->nameSpace : ns); |
| 1187 | name.Assign(&decl[nameNode->tokenPos], nameNode->tokenLength); |
| 1188 | type.MakeReference(isReference); |
| 1189 | |
| 1190 | // Validate that the type really can be a registered property |
| 1191 | // We cannot use CanBeInstantiated, as it is allowed to register |
| 1192 | // properties of type that cannot otherwise be instantiated |
| 1193 | if( type.IsFuncdef() && !type.IsObjectHandle() ) |
| 1194 | { |
| 1195 | // Function definitions must always be handles |
| 1196 | return asINVALID_DECLARATION; |
| 1197 | } |
| 1198 | |
| 1199 | // Verify property name |
| 1200 | if( dt ) |
| 1201 | { |
| 1202 | if( CheckNameConflictMember(dt->GetTypeInfo(), name.AddressOf(), nameNode, &source, true, false) < 0 ) |
| 1203 | return asNAME_TAKEN; |
| 1204 | } |
| 1205 | else |
| 1206 | { |
| 1207 | if( CheckNameConflict(name.AddressOf(), nameNode, &source, ns, true, false, false) < 0 ) |
| 1208 | return asNAME_TAKEN; |
| 1209 | } |
no test coverage detected