/// <summary> /// If a given resolved entry points to a namespace, then new uninstantiated <see cref="TypeOrNamespaceModuleLiteral"/> will be created. /// </summary> /// <remarks> /// This method plays a crucial role in qualifiers implementation. /// In V1 the current qualifier of a nested namespace is searched by looking up until the current qualifier of the parent file /// module literal is found. So when instantiating a new module, its child namespaces need to be chained to it. /// </remarks> private ResolvedEntry CreateResolvedEntryWithNewlyCreatedModuleIfNeeded(ResolvedEntry resolvedEntry, QualifierValue qualifier) { if (!(resolvedEntry.Expression is TypeOrNamespaceModuleLiteral typeOrNamespace)) { return(resolvedEntry); } var newM = new TypeOrNamespaceModuleLiteral(typeOrNamespace.Id, qualifier, this, typeOrNamespace.Location); return(new ResolvedEntry(FullSymbol.Invalid, newM)); }
/// <summary> /// Evaluates a member using by resolving a symbol by a full name. /// </summary> /// <remarks> /// DScript V2 feature. /// </remarks> internal EvaluationResult EvaluateEntryByFullName(Context context, FullSymbol fullName, LineInfo location) { ResolvedEntry resolvedEntry = default(ResolvedEntry); if (CurrentFileModule?.TryGetResolvedEntryByFullName(fullName, out resolvedEntry) == true) { return(EvaluateResolvedSymbol(context, this, location, resolvedEntry)); } // 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 by a full name '{fullName.ToString(context.FrontEndContext.SymbolTable)}'"); Contract.Assert(false, message); return(EvaluationResult.Undefined); }
/// <nodoc /> private FileModuleLiteral(BuildXLReader reader, PathTable pathTable, AbsolutePath path, Package package, GlobalModuleLiteral outerScope, ModuleRegistry moduleRegistry, LineMap lineMap) : this(path, QualifierValue.Unqualified, outerScope, package, moduleRegistry, lineMap) { var context = new DeserializationContext(this, reader, pathTable, lineMap); int resolveEntries = reader.ReadInt32Compact(); for (int i = 0; i < resolveEntries; i++) { FilePosition location = ReadFilePosition(reader); var resolvedEntry = ResolvedEntry.ReadResolvedEntry(context); AddResolvedEntry(location, resolvedEntry); if (resolvedEntry.SymbolName.IsValid) { AddResolvedEntry(resolvedEntry.SymbolName, resolvedEntry); } } }
private Task <object> GetEvaluateResolvedEntryTaskAsync(Context context, QualifierId qualifier, FilePosition filePosition, ResolvedEntry resolvedEntry) { if (resolvedEntry.ResolverCallback != null) { return(EvaluateResolverCallback(context, qualifier, filePosition, resolvedEntry)); } return(context.EvaluationScheduler.EvaluateValue( () => Task.FromResult(EvaluateResolvedEntry(context, qualifier, filePosition, resolvedEntry).Value))); }
private static ModuleBinding ToModuleBinding(ResolvedEntry entry) { return(new ModuleBinding(entry.GetValue(), Declaration.DeclarationFlags.None, entry.Location)); }
private static string GetSymbolNameAsString(ResolvedEntry entry, SymbolTable symbolTable) { return(entry.Function != null ? entry.Function.Name.ToDisplayString(symbolTable.StringTable) : entry.SymbolName.ToDisplayString(symbolTable)); }
private static string GetSymbolNameAsString(ResolvedEntry entry, Context context) { return(entry.Function != null ? entry.Function.Name.ToDisplayString(context) : entry.SymbolName.ToDisplayString(context)); }
/// <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)); }
/// <summary> /// Stores a given resolved entry by a given name. /// </summary> public virtual void AddResolvedEntry(FullSymbol fullName, ResolvedEntry entry) { CurrentFileModule?.AddResolvedEntry(fullName, entry); }
/// <summary> /// Evaluates a resolved entry that is not a Thunk /// </summary> internal EvaluationResult EvaluateNonThunkedResolvedSymbol(Context context, ModuleLiteral module, ResolvedEntry resolvedEntry) { Contract.Assert(resolvedEntry.Thunk == null); if (resolvedEntry.ConstantExpression != null) { return(EvaluationResult.Create(resolvedEntry.ConstantExpression.Value)); } using (var empty = EvaluationStackFrame.Empty()) { if (resolvedEntry.Expression != null) { if (resolvedEntry.Expression is TypeOrNamespaceModuleLiteral namespaceExpression) { // If the resolved entry already evaluated to a namespace and the namespace // is already qualified, then there is no reason for instantiating it twice. Just reusing it. if (namespaceExpression.Qualifier.IsQualified()) { return(EvaluationResult.Create(namespaceExpression)); } return(EvaluationResult.Create(namespaceExpression.Instantiate(context.ModuleRegistry, GetFileQualifier()))); } return(resolvedEntry.Expression.Eval(context, module, empty)); } if (resolvedEntry.ResolverCallback != null) { return(resolvedEntry.ResolverCallback(context, module, empty).GetAwaiter().GetResult()); } Contract.Assert(resolvedEntry.Function != null); return(resolvedEntry.Function.Eval(context, module, empty)); } }
private EvaluationResult EvaluateResolvedSymbol(Context context, ModuleLiteral module, LineInfo location, ResolvedEntry resolvedEntry) { Contract.Requires(module != null); if (resolvedEntry.Thunk != null) { var thunk = resolvedEntry.Thunk; return(thunk.EvaluateWithNewNamedContext(context, module, resolvedEntry.ThunkContextName, location)); } return(EvaluateNonThunkedResolvedSymbol(context, module, resolvedEntry)); }
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> /// Returns resolved entry by the full name. /// </summary> /// <remarks> /// Implemented in <see cref="FileModuleLiteral"/>. /// </remarks> protected virtual bool TryGetResolvedEntryByFullName(FullSymbol fullName, out ResolvedEntry resolvedEntry) { resolvedEntry = default(ResolvedEntry); 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); }
private async Task <object> EvaluateResolverCallback(Context context, QualifierId qualifier, FilePosition filePosition, ResolvedEntry resolvedEntry) { var qualifierValue = QualifierValue.Create(qualifier, context.QualifierValueCache, context.FrontEndContext.QualifierTable, context.StringTable); var env = InstantiateFileModuleLiteral(context.ModuleRegistry, qualifierValue); using (var args = EvaluationStackFrame.Empty()) { return(await resolvedEntry.ResolverCallback(context, env, args)); } }
private EvaluationResult EvaluateResolvedEntry(Context context, QualifierId qualifier, FilePosition filePosition, ResolvedEntry resolvedEntry) { var qualifierValue = QualifierValue.Create(qualifier, context.QualifierValueCache, context.FrontEndContext.QualifierTable, context.StringTable); var instantiatedModule = InstantiateFileModuleLiteral(context.ModuleRegistry, qualifierValue); if (resolvedEntry.Thunk == null) { return(instantiatedModule.EvaluateNonThunkedResolvedSymbol(context, instantiatedModule, resolvedEntry)); } var name = resolvedEntry.ThunkContextName; return(instantiatedModule.EvaluateByLocation(context, filePosition, name, resolvedEntry.Location)); }
/// <summary> /// Stores a given resolved entry at a given location. /// </summary> public virtual void AddResolvedEntry(FilePosition location, ResolvedEntry entry) { CurrentFileModule?.AddResolvedEntry(location, entry); }