private void CopyBindings(FileModuleLiteral file, QualifierValue qualifier) { // Need to copy resolved bindings from a given module. // This requires direct copy for all resolved symbol except namespaces. // In that case new uninstantiated namespace instance is created. if (file.m_resolvedEntries != null) { // Current instance is still under construction, so no locking is needed for m_resolvedEntries field // ReSharper disable once InconsistentlySynchronizedField m_resolvedEntries = new Dictionary <FilePosition, ResolvedEntry>(); foreach (var kvp in file.m_resolvedEntries) { AddResolvedEntry( kvp.Key, CreateResolvedEntryWithNewlyCreatedModuleIfNeeded(kvp.Value, qualifier)); } } if (file.m_resolvedEntriesByFullName != null) { // Current instance is still under construction, so no locking is needed for m_resolvedEntriesByFullName field // ReSharper disable once InconsistentlySynchronizedField m_resolvedEntriesByFullName = new Dictionary <FullSymbol, ResolvedEntry>(); foreach (var kvp in file.m_resolvedEntriesByFullName) { AddResolvedEntry( kvp.Key, CreateResolvedEntryWithNewlyCreatedModuleIfNeeded(kvp.Value, qualifier)); } } }
private FileModuleLiteral GetFileModuleInstanceFromImportOrExportDeclaration( ModuleRegistry moduleRegistry, AbsolutePath referencedPath) { var importedModuleId = ModuleLiteralId.Create(referencedPath); // Get the uninstantiated version of this file module. UninstantiatedModuleInfo importedModuleInfo = moduleRegistry.GetUninstantiatedModuleInfoByModuleId(importedModuleId); // Evaluate qualifier if specified. QualifierValue qualifierValue = Qualifier; // Instantiate this file module according to the qualifier. FileModuleLiteral importedModule = importedModuleInfo.FileModuleLiteral.InstantiateFileModuleLiteral(moduleRegistry, qualifierValue); return(importedModule); }
private FileModuleLiteral DoInstantiate(FileModuleLiteral module, QualifierValue qualifier, GlobalModuleLiteral outerScope) { Contract.Requires(module != null); Contract.Requires(qualifier != QualifierValue.Unqualified); Interlocked.CompareExchange(ref m_qualifier, qualifier, QualifierValue.Unqualified); if (m_qualifier.QualifierId == qualifier.QualifierId) { // Uninstantiated module becomes the first instance. return(this); } // Create a new file module instance. var newModule = CreateInstantiatedFileModule(module.Id.Path, qualifier, outerScope, module.Package, module.m_moduleRegistry, LineMap); newModule.CopyBindings(module, qualifier); return(newModule); }
/// <inheritdoc/> public override bool TryGetResolvedEntry(ModuleRegistry moduleRegistry, FilePosition location, out ResolvedEntry resolvedEntry, out FileModuleLiteral resolvedModule) { if (location.Path != Path) { // TODO:ST: instantiation is happening more than once! var referencedModule = GetFileModuleInstanceFromImportOrExportDeclaration(moduleRegistry, location.Path); return(referencedModule.TryGetResolvedEntry(moduleRegistry, location, out resolvedEntry, out resolvedModule)); } resolvedModule = this; return(m_resolvedEntries.TryGetValue(location, out resolvedEntry)); }
private TypeOrNamespaceModuleLiteral DoInstantiate(ModuleRegistry moduleRegistry, TypeOrNamespaceModuleLiteral module, QualifierValue qualifier, FileModuleLiteral outerScope) { Contract.Requires(module != null); Contract.Requires(qualifier != QualifierValue.Unqualified); Interlocked.CompareExchange(ref m_qualifier, qualifier, QualifierValue.Unqualified); // The outer scope of this should have the same qualifier. So if that's not the case we instantiate one and set the parent appropriately if (outerScope.Qualifier.QualifierId != qualifier.QualifierId) { var newOuterScope = moduleRegistry.InstantiateModule( (outerScope, moduleRegistry, qualifier), QualifiedModuleId.Create(outerScope.Id, qualifier.QualifierId), (state, qualifiedModuleId) => { var capturedOuterScope = state.outerScope; var capturedModuleRegistry = state.moduleRegistry; var capturedQualifier = state.qualifier; return(capturedOuterScope.InstantiateFileModuleLiteral(capturedModuleRegistry, capturedQualifier)); }); return(new TypeOrNamespaceModuleLiteral(module.Id, qualifier, newOuterScope, module.Location)); } if (m_qualifier.QualifierId == qualifier.QualifierId) { // Uninstantiated module becomes the first instance. return(this); } // Create a new file module instance. return(new TypeOrNamespaceModuleLiteral(module.Id, qualifier, outerScope, module.Location)); }
private bool TryResolveEntryByLocation(Context context, FilePosition filePosition, FullSymbol nameForDebuggingPurposes, out ResolvedEntry resolvedEntry, out FileModuleLiteral owningFileModule) { owningFileModule = default(FileModuleLiteral); resolvedEntry = default(ResolvedEntry); if (CurrentFileModule?.TryGetResolvedEntry(context.ModuleRegistry, filePosition, out resolvedEntry, out owningFileModule) == true) { return(true); } // This is an assertion but not a graceful error, because resolution may fail only if something went wrong. string message = I($"Can't find resolved symbol '{nameForDebuggingPurposes.ToString(context.FrontEndContext.SymbolTable)}' at position '{filePosition.Position}' from source file '{filePosition.Path.ToString(context.PathTable)}'"); Contract.Assert(false, message); return(false); }
/// <summary> /// Evaluates a resolved entry that is not a Thunk /// </summary> internal bool TryResolveFunction(Context context, FilePosition filePosition, FullSymbol nameForDebuggingPurposes, out FunctionLikeExpression lambda, out FileModuleLiteral file) { if (TryResolveEntryByLocation(context, filePosition, nameForDebuggingPurposes, out var resolvedEntry, out file)) { lambda = resolvedEntry.Function; return(true); } lambda = null; return(false); }
/// <summary> /// Returns resolved entry by position. /// </summary> /// <remarks> /// Implemented in <see cref="FileModuleLiteral"/>. /// </remarks> public virtual bool TryGetResolvedEntry(ModuleRegistry moduleRegistry, FilePosition location, out ResolvedEntry resolvedEntry, out FileModuleLiteral resolvedModule) { resolvedEntry = default(ResolvedEntry); resolvedModule = null; return(false); }