public PapyrusProgram( ProgramOptions options, IFileSystem fileSystem, IScriptTextProvider textProvider, ILogger <PapyrusProgram> logger, ILogger <ScriptFile> scriptFileLogger, ILogger <FlagsFile> flagsFileLogger) { _options = options.Clone(); _fileSystem = fileSystem; _textProvider = textProvider; _logger = logger; _scriptFileLogger = scriptFileLogger; _flagsFile = new FlagsFile(this, textProvider, flagsFileLogger); _typeChecker = new TypeChecker(this); }
public FlagsFile(PapyrusProgram program, IScriptTextProvider textProvider, ILogger <FlagsFile> logger) { _program = program; _textProvider = textProvider; _logger = logger; // TODO: Invalidate this _flagsFilePath = new CachedValue <string>(() => _program.GetFlagsFilePath().WaitForResult()); _scriptText = new TokenEqualityCachedValue <ScriptText, string>( () => _textProvider.GetText(_flagsFilePath).WaitForResult(), (_) => _textProvider.GetTextVersion(_flagsFilePath).WaitForResult()); _textProvider.OnScriptTextChanged += HandleScriptTextChanged; _parseResult = new TokenEqualityCachedValue <DiagnosticResult <dynamic>, string>(() => { return(DiagnosticResult <dynamic> .TryWithDiagnostics((diagnostics) => { void errorHandler(object s, ErrorEventArgs e) { diagnostics.Add(e.ToDiagnostic()); } var flagsLexer = new FlagsLexer(new CaseInsensitiveStringStream(_scriptText.Value.Text)); flagsLexer.OnError(errorHandler); var flagsParser = new FlagsParser(new CommonTokenStream(flagsLexer)); flagsParser.OnError(errorHandler); flagsParser.flags(); return flagsParser.AsDynamic().DefinedFlags; })); }, (_) => _scriptText.Value.Version); }
public static void SetTextProvider(IScriptTextProvider textProvider) { _textProvider = textProvider; }
public ScriptFile(ObjectIdentifier id, string filePath, PapyrusProgram program, IScriptTextProvider textProvider, ILogger <ScriptFile> logger) { _id = id; _filePath = filePath; _program = program; _textProvider = textProvider; _logger = logger; var initialVersion = _textProvider.GetTextVersion(_filePath).WaitForResult(); _scriptText = new TokenEqualityCachedValue <ScriptText, string>( () => _textProvider.GetText(_filePath).WaitForResult(), (_) => { var currentVersion = _scriptText.CurrentToken; var version = _textProvider.GetTextVersion(_filePath).WaitForResult(); if (currentVersion != version) { _logger.LogTrace($"{_id} file version changed from '{currentVersion}' to '{version}'. (Thread: {Thread.CurrentThread.ManagedThreadId})"); } return(version); }, initialVersion); _textProvider.OnScriptTextChanged += HandleScriptTextChanged; _compiler = new TokenEqualityCachedValue <ScriptCompiler, string>(() => { var compiler = new ScriptCompiler(this, _logger); compiler.CompilerNotifyHandler += (s, e) => { _logger.LogTrace($"Compiler: {e.sMessage}"); }; return(compiler); }, (_) => _scriptText.Value.Version, initialVersion); _compilationResult = new TokenEqualityCachedValue <DiagnosticResult <CompilationResult>, ScriptCompiler>(() => { DiagnosticResult <CompilationResult> compileFunc() { return(DiagnosticResult <CompilationResult> .TryWithDiagnostics((diagnostics) => { return UseCompiler((compiler, types) => { var compilationResult = new CompilationResult(); _logger.LogTrace($"Compiling {_id}... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var type = compiler.Load(types); compilationResult.CompilerType = type; compilationResult.CompilerNode = type?.GetAst(); _logger.LogTrace($"Type checking {_id}... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var typeWalker = new TypeWalker(this, type, _logger); typeWalker.OnError((s, e) => { if (!e.ErrorText.StartsWith("mismatched tree node")) { diagnostics.Add(e.ToDiagnostic()); } }); try { #if FALLOUT4 typeWalker.script(type, compiler, types); #elif SKYRIM lock (types) { if (types.ContainsKey("int")) { types.Remove("int"); types.Remove("float"); types.Remove("string"); types.Remove("bool"); } } typeWalker.script(type, compiler, types, new Stack <string>()); #endif } catch (Exception e) { _logger.LogWarning(e, $"Thrown during type checking of {_id}"); } return compilationResult; }, (s, e) => { diagnostics.Add(e.ToDiagnostic()); }); })); } // If there are diagnostic errors, we re-run the compile once in case anything was missing, // but couldn't be resolved at the time. var result = compileFunc(); if (result.Diagnostics.Count > 0) { return(compileFunc()); } return(result); }, (_) => _compiler.Value); _node = new TokenEqualityCachedValue <DiagnosticResult <ScriptNode>, CompilationResult>(() => { if (CompilerType == null) { return(null); } _logger.LogTrace($"Transforming {_id} syntax tree... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var nodeBinder = new NodeBinder(); var node = nodeBinder.Bind(this, _program, Text, CompilerType.GetTokenStream(), CompilerNode); _logger.LogTrace($"Binding script scopes to {_id} syntax tree... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var scopeBinder = new ScopeBinder(); var scopeResult = scopeBinder.Bind(CompilerType, node.Value); node.Diagnostics.AddRange(scopeResult.Diagnostics); _logger.LogTrace($"Binding {_id} symbols... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var symbolBinder = new SymbolBinder(); var symbolResult = symbolBinder.Bind(node.Value); node.Diagnostics.AddRange(symbolResult.Diagnostics); return(node); }, (_) => _compilationResult.Value?.Value); _type = new TokenEqualityCachedValue <ScriptType, ScriptSymbol>(() => { if (Symbol == null) { return(null); } _logger.LogTrace($"Creating {_id} type... (Thread: {Thread.CurrentThread.ManagedThreadId})"); return(new ScriptType(Program, Symbol, CompilerType)); }, (_) => Symbol); }
public TextDocumentScriptTextProvider(IScriptTextProvider baseProvider, ILogger <TextDocumentScriptTextProvider> logger) { _logger = logger; _baseProvider = baseProvider; }