void ResolveBaseTypes(Boo.Lang.List visited, TypeDefinition node) { visited.Add(node); int removed = 0; int index = 0; foreach (SimpleTypeReference type in node.BaseTypes.ToArray()) { NameResolutionService.ResolveSimpleTypeReference(type); AbstractInternalType internalType = type.Entity as AbstractInternalType; if (null != internalType) { if (visited.Contains(internalType.TypeDefinition)) { Error(CompilerErrorFactory.InheritanceCycle(type, internalType.FullName)); node.BaseTypes.RemoveAt(index - removed); ++removed; } else { ResolveBaseTypes(visited, internalType.TypeDefinition); } } ++index; } }
private void CheckForCycles(TypeReference baseTypeRef, AbstractInternalType baseType, List <TypeDefinition> visited) { if (visited.Contains(baseType.TypeDefinition)) { BaseTypeError(CompilerErrorFactory.InheritanceCycle(baseTypeRef, baseType.FullName)); return; } new BaseTypeResolution(Context, baseType.TypeDefinition, visited); }
private void Run() { IType type = (IType)TypeSystemServices.GetEntity(_typeDefinition); EnterGenericParametersNamespace(type); List <TypeDefinition> visitedNonInterfaces = null; List <TypeDefinition> visitedInterfaces; if (_typeDefinition is InterfaceDefinition) { visitedInterfaces = _visited; // interfaces won't have noninterface base types so visitedNonInterfaces not necessary here } else { visitedNonInterfaces = _visited; visitedInterfaces = new List <TypeDefinition>(); } foreach (var baseTypeRef in _typeDefinition.BaseTypes.ToArray()) { NameResolutionService.ResolveTypeReference(baseTypeRef); ++_index; AbstractInternalType baseType = baseTypeRef.Entity as AbstractInternalType; if (null == baseType) { continue; } if (IsEnclosingType(baseType.TypeDefinition)) { BaseTypeError(CompilerErrorFactory.NestedTypeCannotExtendEnclosingType(baseTypeRef, type, baseType)); continue; } // Clone visited for siblings re https://github.com/bamboo/boo/issues/94 if (baseType is InternalInterface) { CheckForCycles(baseTypeRef, baseType, new List <TypeDefinition>(visitedInterfaces)); } else { CheckForCycles(baseTypeRef, baseType, new List <TypeDefinition>(visitedNonInterfaces)); } } LeaveGenericParametersNamespace(type); }
bool IsAbstract(IType type) { if (type.IsAbstract) { return(true); } AbstractInternalType internalType = type as AbstractInternalType; if (null != internalType) { return(_newAbstractClasses.Contains(internalType.TypeDefinition)); } return(false); }
void ResolveBaseTypes(Boo.Lang.List visited, TypeDefinition node) { // If type is generic, enter a special namespace to allow // correct resolution of generic parameters IType type = (IType)TypeSystemServices.GetEntity(node); if (type.GenericInfo != null) { EnterNamespace(new GenericParametersNamespaceExtender( type, NameResolutionService.CurrentNamespace)); } visited.Add(node); int removed = 0; int index = 0; foreach (SimpleTypeReference baseType in node.BaseTypes.ToArray()) { NameResolutionService.ResolveSimpleTypeReference(baseType); AbstractInternalType internalType = baseType.Entity as AbstractInternalType; if (null != internalType) { if (visited.Contains(internalType.TypeDefinition)) { Error(CompilerErrorFactory.InheritanceCycle(baseType, internalType.FullName)); node.BaseTypes.RemoveAt(index - removed); ++removed; } else { ResolveBaseTypes(visited, internalType.TypeDefinition); } } ++index; } // Leave special namespace if we entered it before if (type.GenericInfo != null) { LeaveNamespace(); } }