bool asCBuilder::DoesMethodExist(asCObjectType *objType, int methodId) { asCScriptFunction *method = GetFunctionDescription(methodId); for( asUINT n = 0; n < objType->methods.GetLength(); n++ ) { asCScriptFunction *m = GetFunctionDescription(objType->methods[n]); if( m->name != method->name ) continue; if( m->returnType != method->returnType ) continue; if( m->isReadOnly != method->isReadOnly ) continue; if( m->parameterTypes != method->parameterTypes ) continue; if( m->inOutFlags != method->inOutFlags ) continue; return true; } return false; }
int asCBuilder::RegisterImportedFunction(int importID, asCScriptNode *node, asCScriptCode *file) { // Find name asCScriptNode *f = node->firstChild; asCScriptNode *n = f->firstChild->next->next; // Check for name conflicts GETSTRING(name, &file->code[n->tokenPos], n->tokenLength); CheckNameConflict(name.AddressOf(), n, file); // Initialize a script function object for registration asCDataType returnType; returnType = CreateDataTypeFromNode(f->firstChild, file); returnType = ModifyDataTypeFromNode(returnType, f->firstChild->next, file, 0, 0); asCArray<asCDataType> parameterTypes; asCArray<int> inOutFlags; n = n->next->firstChild; while( n ) { int inOutFlag; asCDataType type = CreateDataTypeFromNode(n, file); type = ModifyDataTypeFromNode(type, n->next, file, &inOutFlag, 0); // Store the parameter type n = n->next->next; parameterTypes.PushLast(type); inOutFlags.PushLast(inOutFlag); // Move to next parameter if( n && n->nodeType == snIdentifier ) n = n->next; } // Check that the same function hasn't been registered already asCArray<int> funcs; GetFunctionDescriptions(name.AddressOf(), funcs); if( funcs.GetLength() ) { for( asUINT n = 0; n < funcs.GetLength(); ++n ) { asCScriptFunction *func = GetFunctionDescription(funcs[n]); // TODO: Isn't the name guaranteed to be equal, because of GetFunctionDescriptions()? if( name == func->name && parameterTypes.GetLength() == func->parameterTypes.GetLength() ) { bool match = true; for( asUINT p = 0; p < parameterTypes.GetLength(); ++p ) { if( parameterTypes[p] != func->parameterTypes[p] ) { match = false; break; } } if( match ) { int r, c; file->ConvertPosToRowCol(node->tokenPos, &r, &c); WriteError(file->name.AddressOf(), TXT_FUNCTION_ALREADY_EXIST, r, c); break; } } } } // Read the module name as well n = node->firstChild->next; int moduleNameString = module->AddConstantString(&file->code[n->tokenPos+1], n->tokenLength-2); delete node; // Register the function module->AddImportedFunction(importID, name.AddressOf(), returnType, parameterTypes.AddressOf(), inOutFlags.AddressOf(), (asUINT)parameterTypes.GetLength(), moduleNameString); return 0; }
int asCBuilder::RegisterScriptFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface) { // Find name bool isConstructor = false; asCScriptNode *n = 0; if( node->firstChild->nodeType == snDataType ) n = node->firstChild->next->next; else { n = node->firstChild; isConstructor = true; } // Check for name conflicts GETSTRING(name, &file->code[n->tokenPos], n->tokenLength); if( !isConstructor ) CheckNameConflict(name.AddressOf(), n, file); else { // Verify that the name of the function is the same as the class if( name != objType->name ) { int r, c; file->ConvertPosToRowCol(n->tokenPos, &r, &c); WriteError(file->name.AddressOf(), TXT_CONSTRUCTOR_NAME_ERROR, r, c); } } if( !isInterface ) { sFunctionDescription *func = new sFunctionDescription; functions.PushLast(func); func->script = file; func->node = node; func->name = name; func->objType = objType; func->funcId = funcID; } // Initialize a script function object for registration asCDataType returnType = asCDataType::CreatePrimitive(ttVoid, false); if( !isConstructor ) { returnType = CreateDataTypeFromNode(node->firstChild, file); returnType = ModifyDataTypeFromNode(returnType, node->firstChild->next, file, 0, 0); module->RefConfigGroupForObjectType(returnType.GetObjectType()); } asCArray<asCDataType> parameterTypes; asCArray<int> inOutFlags; n = n->next->firstChild; while( n ) { int inOutFlag; asCDataType type = CreateDataTypeFromNode(n, file); type = ModifyDataTypeFromNode(type, n->next, file, &inOutFlag, 0); module->RefConfigGroupForObjectType(type.GetObjectType()); // Store the parameter type parameterTypes.PushLast(type); inOutFlags.PushLast(inOutFlag); // Move to next parameter n = n->next->next; if( n && n->nodeType == snIdentifier ) n = n->next; } // Check that the same function hasn't been registered already asCArray<int> funcs; GetFunctionDescriptions(name.AddressOf(), funcs); if( funcs.GetLength() ) { for( asUINT n = 0; n < funcs.GetLength(); ++n ) { asCScriptFunction *func = GetFunctionDescription(funcs[n]); if( parameterTypes.GetLength() == func->parameterTypes.GetLength() ) { bool match = true; for( asUINT p = 0; p < parameterTypes.GetLength(); ++p ) { if( parameterTypes[p] != func->parameterTypes[p] ) { match = false; break; } } if( match ) { int r, c; file->ConvertPosToRowCol(node->tokenPos, &r, &c); WriteError(file->name.AddressOf(), TXT_FUNCTION_ALREADY_EXIST, r, c); break; } } } } // Register the function module->AddScriptFunction(file->idx, funcID, name.AddressOf(), returnType, parameterTypes.AddressOf(), inOutFlags.AddressOf(), (asUINT)parameterTypes.GetLength(), isInterface, objType); if( objType ) { if( isConstructor ) { if( parameterTypes.GetLength() == 0 ) { // Overload the default constructor objType->beh.construct = funcID; objType->beh.constructors[0] = funcID; } else objType->beh.constructors.PushLast(funcID); } else objType->methods.PushLast(funcID); } // We need to delete the node already if this is an interface method if( isInterface && node ) delete node; return 0; }
int asCBuilder::RegisterScriptFunction(int funcID, asCScriptNode *node, asCScriptCode *file) { // Find name asCScriptNode *n = node->firstChild->next->next; // Check for name conflicts GETSTRING(name, &file->code[n->tokenPos], n->tokenLength); CheckNameConflict(name.AddressOf(), n, file); sFunctionDescription *func = new sFunctionDescription; functions.PushLast(func); func->script = file; func->node = node; func->name = name; // Initialize a script function object for registration asCDataType returnType; returnType = CreateDataTypeFromNode(node->firstChild, file); returnType = ModifyDataTypeFromNode(returnType, node->firstChild->next, 0, 0); module->RefConfigGroupForObjectType(returnType.GetObjectType()); asCArray<asCDataType> parameterTypes; asCArray<int> inOutFlags; n = n->next->firstChild; while( n ) { int inOutFlag; asCDataType type = CreateDataTypeFromNode(n, file); type = ModifyDataTypeFromNode(type, n->next, &inOutFlag, 0); module->RefConfigGroupForObjectType(type.GetObjectType()); // Store the parameter type parameterTypes.PushLast(type); inOutFlags.PushLast(inOutFlag); // Move to next parameter n = n->next->next; if( n && n->nodeType == snIdentifier ) n = n->next; } // Check that the same function hasn't been registered already asCArray<int> funcs; GetFunctionDescriptions(name.AddressOf(), funcs); if( funcs.GetLength() ) { for( asUINT n = 0; n < funcs.GetLength(); ++n ) { asCScriptFunction *func = GetFunctionDescription(funcs[n]); if( parameterTypes.GetLength() == func->parameterTypes.GetLength() ) { bool match = true; for( asUINT p = 0; p < parameterTypes.GetLength(); ++p ) { if( parameterTypes[p] != func->parameterTypes[p] ) { match = false; break; } } if( match ) { int r, c; file->ConvertPosToRowCol(node->tokenPos, &r, &c); WriteError(file->name.AddressOf(), TXT_FUNCTION_ALREADY_EXIST, r, c); break; } } } } // Register the function module->AddScriptFunction(file->idx, funcID, func->name.AddressOf(), returnType, parameterTypes.AddressOf(), inOutFlags.AddressOf(), parameterTypes.GetLength()); return 0; }