//^ ensures result == null || result is ITypeDefinition || result is INamespaceDefinition || result is ITypeGroup || //^ (!restrictToNamespacesAndTypes && result is INamespaceMember); /// <summary> /// Returns either null or the namespace member (group) that binds to this name. /// This implementation of this method ignores global methods and variables, as is the case for C#. //TODO: is this really the case? /// </summary> /// <param name="namespaceDeclaration">The namespace to use to resolve this name.</param> /// <param name="restrictToNamespacesAndTypes">True if only namespaces and types should be considered when resolving this name.</param> /*?*/ protected override object ResolveUsing(NamespaceDeclaration namespaceDeclaration, bool restrictToNamespacesAndTypes) { // Overrides the SimpleName's corresponding method so that we can handle the scope encoding // (the mangled C type names to encode scope information) string lookupNameString = this.Name.Value; // loop until we have tried every parent scope while (true) { IScope<INamespaceMember> scope = namespaceDeclaration.UnitNamespace; IName lookupName = this.NameTable.GetNameFor(lookupNameString); AliasDeclaration/*?*/ aliasDeclaration = null; UnitSetAliasDeclaration/*?*/ unitSetAliasDeclaration = null; if (!this.NamespaceDeclIsBusy(namespaceDeclaration)) namespaceDeclaration.GetAliasNamed(lookupName, this.IgnoreCase, ref aliasDeclaration, ref unitSetAliasDeclaration); IEnumerable<INamespaceMember> members = scope.GetMembersNamed(lookupName, this.IgnoreCase); INamespaceTypeDefinition/*?*/ namespaceTypeDefinition = null; INamespaceDefinition/*?*/ nestedNamespaceDefinition = null; foreach (INamespaceMember member in members) { nestedNamespaceDefinition = member as INamespaceDefinition; if (nestedNamespaceDefinition != null) { //TODO: if aliasDeclaration != null give an ambiguous reference error return nestedNamespaceDefinition; } if (namespaceTypeDefinition == null) { namespaceTypeDefinition = member as INamespaceTypeDefinition; if (namespaceTypeDefinition != null && (aliasDeclaration == null || namespaceTypeDefinition.IsGeneric)) break; //carry on in case there is a generic type with this name. If not there is an ambiguity between the type and the alias. } } if (namespaceTypeDefinition != null) { //TODO: if aliasDeclaration != null give an ambiguous reference error if namespaceTypeDef is not generic if (this.Name.Value == lookupNameString) { return new NamespaceTypeGroup(this, scope, this); } VccSimpleName newSimpleName = new VccSimpleName(lookupName, this.sourceLocation); newSimpleName.SetContainingBlock(this.ContainingBlock); return new NamespaceTypeGroup(this, scope, newSimpleName); } if (this.NamespaceDeclIsBusy(namespaceDeclaration)) { //Have to ignore using statements. scope = namespaceDeclaration.UnitSetNamespace; members = scope.GetMembersNamed(lookupName, this.IgnoreCase); } else { if (aliasDeclaration != null) return aliasDeclaration.ResolvedNamespaceOrType; if (unitSetAliasDeclaration != null) { IUnitSetNamespace usns = unitSetAliasDeclaration.UnitSet.UnitSetNamespaceRoot; //^ assume usns is INamespaceDefinition; //IUnitSetNamespace : INamespaceDefinition return usns; } scope = namespaceDeclaration.Scope; members = scope.GetMembersNamed(lookupName, this.IgnoreCase); //Considers types that were imported into the namespace via using statements } foreach (INamespaceMember member in members) { if (nestedNamespaceDefinition == null) nestedNamespaceDefinition = member as INamespaceDefinition; namespaceTypeDefinition = member as INamespaceTypeDefinition; if (namespaceTypeDefinition != null) return new NamespaceTypeGroup(this, scope, this); } if (nestedNamespaceDefinition != null) return nestedNamespaceDefinition; // Test to see if we have reached the outermost scope, in which case lookupNameString // is not a mangled one. if (!lookupNameString.Contains("^")) break; lookupNameString = LexicalScope.LexicalScopeOf(lookupNameString) == "" ? LexicalScope.UnmangledName(lookupNameString) : LexicalScope.MangledNameWithOuterLexcialScope(lookupNameString); } // The following (looking the name up in the nested namespace) // may not apply to the C case. Keep it here anyway. NestedNamespaceDeclaration/*?*/ nestedNamespace = namespaceDeclaration as NestedNamespaceDeclaration; if (nestedNamespace != null) return this.ResolveUsing(nestedNamespace.ContainingNamespaceDeclaration, restrictToNamespacesAndTypes); return null; }
//^ requires template.ContainingBlock != containingBlock; //^ ensures this.containingBlock == containingBlock; /// <summary> /// A copy constructor that allocates an instance that is the same as the given template, except for its containing block. /// </summary> /// <param name="containingBlock">A new value for containing block. This replaces template.ContainingBlock in the resulting copy of template.</param> /// <param name="template">The template to copy.</param> protected VccSimpleName(BlockStatement containingBlock, VccSimpleName template) : base(containingBlock, template) { }