def parse( cls, filepath: str, build_file_content: str, parser: Parser, extra_symbols: BuildFilePreludeSymbols, ) -> AddressMap: """Parses a source for targets. The target adaptors are all 'thin': any targets they point to in other namespaces or even in the same namespace but from a separate source are left as unresolved pointers. """ try: target_adaptors = parser.parse(filepath, build_file_content, extra_symbols) except Exception as e: raise MappingError(f"Failed to parse ./{filepath}:\n{e}") name_to_target_adaptors: dict[str, TargetAdaptor] = {} for target_adaptor in target_adaptors: name = target_adaptor.name if name in name_to_target_adaptors: duplicate = name_to_target_adaptors[name] raise DuplicateNameError( f"A target already exists at {filepath!r} with name {name!r} and target type " f"{duplicate.type_alias!r}. The {target_adaptor.type_alias!r} target " "cannot use the same name.") name_to_target_adaptors[name] = target_adaptor return cls(filepath, dict(sorted(name_to_target_adaptors.items())))
def parse(cls, filepath: str, filecontent: bytes, parser: Parser) -> "AddressMap": """Parses a source for addressable Serializable objects. No matter the parser used, the parsed and mapped addressable objects are all 'thin'; ie: any objects they point to in other namespaces or even in the same namespace but from a separate source are left as unresolved pointers. :param filepath: The path to the byte source containing serialized objects. :param filecontent: The content of byte source containing serialized objects to be parsed. :param parser: The parser cls to use. """ try: objects = parser.parse(filepath, filecontent) except Exception as e: raise MappingError(f"Failed to parse {filepath}:\n{e!r}") objects_by_name: Dict[str, ThinAddressableObject] = {} for obj in objects: if not Serializable.is_serializable(obj): raise UnaddressableObjectError("Parsed a non-serializable object: {!r}".format(obj)) attributes = obj._asdict() name = attributes.get("name") if not name: raise UnaddressableObjectError("Parsed a non-addressable object: {!r}".format(obj)) if name in objects_by_name: raise DuplicateNameError( "An object already exists at {!r} with name {!r}: {!r}. Cannot " "map {!r}".format(filepath, name, objects_by_name[name], obj) ) objects_by_name[name] = obj return cls(filepath, dict(sorted(objects_by_name.items())))