| 1836 | } |
| 1837 | |
| 1838 | void AddSetVariableNode(const char* pos) |
| 1839 | { |
| 1840 | CodeInfo::lastKnownStartPos = pos; |
| 1841 | |
| 1842 | // Take l-value |
| 1843 | NodeZeroOP *left = CodeInfo::nodeList[CodeInfo::nodeList.size()-2]; |
| 1844 | // If we have a function call as an l-value... |
| 1845 | if(left->nodeType == typeNodeFuncCall && ((NodeFuncCall*)left)->funcInfo) |
| 1846 | { |
| 1847 | // ...and that was an accessor "get" function call, we have to replace "get" function with "set" function |
| 1848 | FunctionInfo *fInfo = ((NodeFuncCall*)left)->funcInfo; |
| 1849 | if(fInfo->name[fInfo->nameLength-1] == '$') |
| 1850 | { |
| 1851 | // Replace function call node with 'this' pointer that function node had |
| 1852 | CodeInfo::nodeList[CodeInfo::nodeList.size()-2] = ((NodeFuncCall*)left)->GetFirstNode(); |
| 1853 | // If this is an accessor of a generic type, maybe we have to instance a "set" accessor function |
| 1854 | if(fInfo->parentClass && fInfo->parentClass->genericBase) |
| 1855 | { |
| 1856 | TypeInfo *currentType = fInfo->parentClass; |
| 1857 | // Get hash of the base class accessor name |
| 1858 | unsigned accessorBaseHash = currentType->genericBase->nameHash; |
| 1859 | accessorBaseHash = StringHashContinue(accessorBaseHash, "::"); |
| 1860 | const char *skipClassName = strchr(fInfo->name, ':'); |
| 1861 | assert(skipClassName); |
| 1862 | accessorBaseHash = StringHashContinue(accessorBaseHash, skipClassName + 2); |
| 1863 | // Clear selected function list |
| 1864 | bestFuncList.clear(); |
| 1865 | SelectFunctionsForHash(accessorBaseHash, 0); // Select accessor functions from generic type base class |
| 1866 | SelectFunctionsForHash(fInfo->nameHash, 0); // Select accessor functions from instanced class |
| 1867 | // Select best function for the call |
| 1868 | unsigned minRating = ~0u; |
| 1869 | unsigned minRatingIndex = SelectBestFunction(bestFuncList.size(), 1, minRating, currentType); |
| 1870 | if(minRating != ~0u) |
| 1871 | { |
| 1872 | // If a function is found and it is a generic function, instance it |
| 1873 | FunctionInfo *fInfo = bestFuncList[minRatingIndex]; |
| 1874 | if(fInfo && fInfo->generic) |
| 1875 | { |
| 1876 | CreateGenericFunctionInstance(pos, fInfo, fInfo, ~0u, currentType); |
| 1877 | fInfo->parentClass = currentType; |
| 1878 | } |
| 1879 | } |
| 1880 | } |
| 1881 | // Try to call "set" accessor |
| 1882 | if(AddFunctionCallNode(pos, fInfo->name, 1, true)) |
| 1883 | return; // If a call is successful, we are done |
| 1884 | else |
| 1885 | CodeInfo::nodeList[CodeInfo::nodeList.size()-2] = left; // If failed, this is a read-only accessor so return l-value to original state |
| 1886 | } |
| 1887 | } |
| 1888 | |
| 1889 | // Call overloaded operator with error suppression |
| 1890 | if(AddFunctionCallNode(CodeInfo::lastKnownStartPos, "=", 2, true)) |
| 1891 | return; |
| 1892 | // Call default operator with error suppression |
| 1893 | if(AddFunctionCallNode(CodeInfo::lastKnownStartPos, "$defaultAssign", 2, true)) |
| 1894 | return; |
| 1895 |
no test coverage detected