private void fillinMethod(int methodID, boolean isStatic, Record res) {
		MethodIDItem methodIDItem = dexHeader.getMethods().get(methodID);
		Address addr = dexHeader.getMethodAddress(program, methodID);
		res.token = null;
		String namespaceString = null;
		if (addr != Address.NO_ADDRESS) {
			Symbol symbol = program.getSymbolTable().getPrimarySymbol(addr);
			if (symbol != null && symbol.getSource() != SourceType.DEFAULT) {
				res.token = symbol.getName();
				res.token = removeUniquifier(res.token);
				namespaceString = symbol.getParentNamespace().getName();
			}
		}
		if (res.token == null) {
			res.token = DexUtil.convertToString(dexHeader, methodIDItem.getNameIndex());
		}
		if (isStatic) {
			if (namespaceString == null) {
				String classString =
					DexUtil.convertTypeIndexToString(dexHeader, methodIDItem.getClassIndex());
				String[] pathArray = DexUtil.convertClassStringToPathArray("", classString);
				if (pathArray != null) {
					namespaceString = pathArray[pathArray.length - 1];
				}
			}
			if (namespaceString != null) {
				res.token = namespaceString + '.' + res.token;
			}
		}
		res.tag = ConstantPool.POINTER_METHOD;
		// The FunctionDefinition is constructed on the fly, essentially as an anonymous type
		// We use an internal naming scheme involding the methodID to avoid name collisions
		String defName = res.token + '_' + Integer.toHexString(methodID);
		FunctionDefinitionDataType funcDef = new FunctionDefinitionDataType(defName, dtManager);
		res.type = new PointerDataType(funcDef);
		try {
			funcDef.setCallingConvention(
				isStatic ? CompilerSpec.CALLING_CONVENTION_stdcall
						: CompilerSpec.CALLING_CONVENTION_thiscall);
		}
		catch (InvalidInputException e) {
			// unexpected
		}

		int prototypeIndex = methodIDItem.getProtoIndex() & 0xffff;
		PrototypesIDItem prototype = dexHeader.getPrototypes().get(prototypeIndex);
		DataType returnDataType =
			dexHeader.getDataType(program, (short) prototype.getReturnTypeIndex());
		funcDef.setReturnType(returnDataType);

		ArrayList<ParameterDefinition> paramDef = new ArrayList<>();
		if (!isStatic) {
			ParameterDefinitionImpl pDef =
				new ParameterDefinitionImpl("ref", Undefined4DataType.dataType, null);
			paramDef.add(pDef);
		}
		TypeList parameters = prototype.getParameters();
		if (parameters != null) {
			for (TypeItem parameterTypeItem : parameters.getItems()) {
				DataType parameterDataType =
					dexHeader.getDataType(program, parameterTypeItem.getType());
				ParameterDefinitionImpl pDef =
					new ParameterDefinitionImpl("", parameterDataType, null);
				paramDef.add(pDef);
			}
		}
		ParameterDefinition finalDefs[] = new ParameterDefinition[paramDef.size()];
		paramDef.toArray(finalDefs);
		funcDef.setArguments(finalDefs);
	}
Map Ghidra's generic ConstantPool interface onto the Dex specific constant pool
Ghidra/Processors/Dalvik/src/main/java/ghidra/dalvik/dex/inject/ConstantPoolDex.java