private static Letter GetLetter(char character, bool exactLetter, ScriptFile script, DocRange range)
        {
            foreach (Letter letter in Alphabet)
            {
                if (character == letter.Character)
                {
                    return(letter);
                }
            }

            if (!exactLetter)
            {
                foreach (Letter letter in Alphabet)
                {
                    if (Char.ToLower(character) == char.ToLower(letter.Character))
                    {
                        return(letter);
                    }
                }
            }

            script.Diagnostics.Error(character + " is not a valid character.", range);
            return(null);
        }
예제 #2
0
 public override void Call(ParseInfo parseInfo, DocRange callRange)
 {
     base.Call(parseInfo, callRange);
     parseInfo.Script.AddDefinitionLink(callRange, DefinedAt);
     AddLink(new LanguageServer.Location(parseInfo.Script.Uri, callRange));
 }
        string GetImportedFile(ScriptFile script, FileImporter importer, DeltinScriptParser.Import_fileContext importFileContext)
        {
            // If the file being imported is being imported as an object, get the variable name.
            string variableName = null;

            if (importFileContext.AS() != null)
            {
                // Syntax error if there is an 'as' keyword but no variable name.
                if (importFileContext.name == null)
                {
                    script.Diagnostics.Error("Expected variable name.", DocRange.GetRange(importFileContext.AS()));
                }
                // Get the variable name.
                else
                {
                    variableName = importFileContext.name.Text;
                }
            }

            DocRange stringRange = DocRange.GetRange(importFileContext.STRINGLITERAL());

            ImportResult importResult = importer.Import(
                stringRange,
                Extras.RemoveQuotes(importFileContext.STRINGLITERAL().GetText()),
                script.Uri
                );

            if (!importResult.SuccessfulReference)
            {
                return(importResult.Directory);
            }

            // Add hover and definition info.
            script.AddDefinitionLink(stringRange, new Location(importResult.Uri, DocRange.Zero));
            script.AddHover(stringRange, importResult.FilePath);

            if (importResult.ShouldImport)
            {
                // Import the file if it should be imported.
                switch (importResult.FileType)
                {
                // Get script file.
                case ".del":
                case ".ostw":
                case ".workshop":
                    ScriptFile importedScript = new ScriptFile(Diagnostics, importResult.Uri, FileGetter.GetScript(importResult.Uri));
                    CollectScriptFiles(importedScript);
                    break;

                // Get lobby settings.
                case ".json":
                    JObject lobbySettings = null;

                    // Make sure the json is in the correct format.
                    try
                    {
                        ImportedScript file = FileGetter.GetImportedFile(importResult.Uri);
                        file.Update();

                        // Convert the json to a jobject.
                        lobbySettings = JObject.Parse(file.Content);

                        // An exception will be thrown if the jobject cannot be converted to a Ruleset.
                        lobbySettings.ToObject(typeof(Ruleset));

                        if (!Ruleset.Validate(lobbySettings, script.Diagnostics, stringRange))
                        {
                            break;
                        }
                    }
                    catch
                    {
                        // Error if the json failed to parse.
                        script.Diagnostics.Error("Failed to parse the settings file.", stringRange);
                        break;
                    }

                    // If no lobby settings were imported yet, set MergedLobbySettings to the jobject.
                    if (MergedLobbySettings == null)
                    {
                        MergedLobbySettings = lobbySettings;
                    }
                    else
                    {
                        // Otherwise, merge current lobby settings.
                        lobbySettings.Merge(MergedLobbySettings, new JsonMergeSettings {
                            MergeArrayHandling     = MergeArrayHandling.Union,
                            MergeNullValueHandling = MergeNullValueHandling.Ignore
                        });
                        MergedLobbySettings = lobbySettings;
                    }
                    break;
                }
            }
            return(importResult.Directory);
        }
 public void Warning(string message, DocRange range)
 {
     _diagnostics.Add(new Diagnostic(message, range, Diagnostic.Warning));
 }
 public void Hint(string message, DocRange range)
 {
     _diagnostics.Add(new Diagnostic(message, range, Diagnostic.Hint));
 }
예제 #6
0
 public TreeContextPart(DeltinScriptParser.MethodContext method)
 {
     this.method     = method ?? throw new ArgumentNullException(nameof(method));
     Range           = DocRange.GetRange(method);
     CompletionRange = DocRange.GetRange(method.PART());
 }
예제 #7
0
        public VariableResolve(VariableResolveOptions options, IExpression expression, DocRange expressionRange, FileDiagnostics diagnostics)
        {
            // The expression is a variable.
            if (expression is CallVariableAction)
            {
                // Get the variable being set and the range.
                SetVariable   = (CallVariableAction)expression;
                VariableRange = expressionRange;
            }
            // The expression is an expression tree.
            else if (expression is ExpressionTree tree)
            {
                Tree = tree;
                if (tree.Completed)
                {
                    // If the resulting expression in the tree is not a variable.
                    if (tree.Result is CallVariableAction == false)
                    {
                        NotAVariableRange = tree.ExprContextTree.Last().Range;
                    }
                    else
                    {
                        // Get the variable and the range.
                        SetVariable   = (CallVariableAction)tree.Result;
                        VariableRange = tree.ExprContextTree.Last().Range;
                    }
                }
            }
            // The expression is not a variable.
            else if (expression != null)
            {
                NotAVariableRange = expressionRange;
            }

            // NotAVariableRange will not be null if the resulting expression is a variable.
            if (NotAVariableRange != null)
            {
                diagnostics.Error("Expected a variable.", NotAVariableRange);
            }

            // Make sure the variable can be set to.
            if (SetVariable != null)
            {
                if (!SetVariable.Calling.Settable())
                {
                    diagnostics.Error($"The variable '{SetVariable.Calling.Name}' cannot be set to.", VariableRange);
                }

                if (options.FullVariable)
                {
                    Var asVar = SetVariable.Calling as Var;
                    if (asVar == null || asVar.StoreType != StoreType.FullVariable)
                    {
                        diagnostics.Error($"The variable '{SetVariable.Calling.Name}' cannot be indexed.", VariableRange);
                    }
                }

                if (!options.CanBeIndexed && SetVariable.Index.Length != 0)
                {
                    diagnostics.Error($"The variable '{SetVariable.Calling.Name}' cannot be indexed.", VariableRange);
                }
            }

            DoesResolveToVariable = SetVariable != null;
        }
예제 #8
0
 public virtual void Call(ScriptFile script, DocRange callRange)
 {
     script.AddHover(callRange, GetLabel(true));
 }
 public OperatorAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_op_boolContext context)
 {
     GetParts(parseInfo, scope, context.left, context.BOOL().GetText(), DocRange.GetRange(context.BOOL()), context.right);
 }
예제 #10
0
 public ReferenceCodeLensRange(ICallable callable, ParseInfo parseInfo, CodeLensSourceType sourceType, DocRange range) : base(sourceType, range, "ostw.showReferences")
 {
     Callable   = callable;
     _parseInfo = parseInfo;
 }
예제 #11
0
 public ImplementsCodeLensRange(IMethod method, ScriptFile script, CodeLensSourceType sourceType, DocRange range) : base(sourceType, range, "ostw.showReferences")
 {
     Method  = method;
     _script = script;
 }
예제 #12
0
 public CodeLensRange(CodeLensSourceType sourceType, DocRange range, string command)
 {
     SourceType = sourceType;
     Range      = range;
     Command    = command;
 }
예제 #13
0
 public ElementCountCodeLens(DocRange range, bool optimized) : base(CodeLensSourceType.None, range, null)
 {
     this.optimized = optimized;
 }
        public static Line[] Create(string text, bool exactLetter, ScriptFile script, DocRange range)
        {
            double      offset = 0;
            List <Line> result = new List <Line>();

            foreach (char character in text)
            {
                Letter letter = GetLetter(character, exactLetter, script, range);
                if (letter == null)
                {
                    return(null);
                }

                if (letter.Lines != null)
                {
                    foreach (var line in letter.Lines)
                    {
                        Line newLine = (Line)line.Clone();
                        newLine.Offset(offset, 0, 0);
                        result.Add(newLine);
                    }
                }

                offset += letter.Width + .15;
            }

            if (result.Count > 0)
            {
                double xOffset = -(result.Max(line => Math.Max(line.Vertex1.X, line.Vertex2.X)) / 2);

                foreach (Line line in result)
                {
                    line.Offset(xOffset, 0, 0);
                }
            }

            foreach (Line line in result)
            {
                line.Vertex1 = line.Vertex1;
                line.Vertex2 = line.Vertex2;
            }

            return(result.ToArray());
        }
예제 #15
0
        public VariableResolve(ParseInfo parseInfo, VariableResolveOptions options, IExpression expression, DocRange expressionRange, IVariableResolveErrorHandler errorHandler)
        {
            bool treeSettable = true;

            // The expression is a variable.
            if (expression is CallVariableAction)
            {
                // Get the variable being set and the range.
                SetVariable   = (CallVariableAction)expression;
                VariableRange = expressionRange;
            }
            // The expression is an expression tree.
            else if (expression is ExpressionTree tree)
            {
                Tree = tree;
                if (tree.Completed)
                {
                    // If the resulting expression in the tree is not a variable.
                    if (tree.Result is CallVariableAction == false)
                    {
                        NotAVariableRange = tree.ExprContextTree.Last().GetRange();
                    }
                    else
                    {
                        // Get the variable and the range.
                        SetVariable   = (CallVariableAction)tree.Result;
                        VariableRange = tree.ExprContextTree.Last().GetRange();
                        treeSettable  = tree.TargetCanBeSet();
                    }
                }
            }
            // The expression is not a variable.
            else if (expression != null)
            {
                NotAVariableRange = expressionRange;
            }

            // NotAVariableRange will not be null if the resulting expression is a variable.
            if (NotAVariableRange != null)
            {
                errorHandler.Error("Expected a variable.", NotAVariableRange);
            }

            // Make sure the variable can be set to.
            if (SetVariable != null)
            {
                // Check if the variable is settable.
                if (options.ShouldBeSettable)
                {
                    // The variable can never be set.
                    if (!SetVariable.Calling.Attributes.CanBeSet)
                    {
                        errorHandler.Error($"The variable '{SetVariable.Calling.Name}' cannot be set", VariableRange);
                    }

                    // The variable is normally settable, but not in the current context.
                    else if (!treeSettable || (parseInfo.ContextualVariableModifiers != null && !parseInfo.ContextualVariableModifiers.IsSettable(SetVariable.Calling)))
                    {
                        errorHandler.Error($"The variable '{SetVariable.Calling.Name}' cannot be set in the current context", VariableRange);
                    }
                }

                // Check if the variable is a whole workshop variable.
                else if ((options.FullVariable && SetVariable.Calling.Attributes.StoreType != StoreType.FullVariable) || (!options.CanBeIndexed && SetVariable.Index.Length != 0))
                {
                    errorHandler.Error($"The variable '{SetVariable.Calling.Name}' cannot be indexed", VariableRange);
                }
            }

            DoesResolveToVariable = SetVariable != null;
        }
 public OperatorAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_op_compareContext context)
 {
     GetParts(parseInfo, scope, context.left, context.op.Text, DocRange.GetRange(context.op), context.right);
 }
예제 #17
0
 public TreeContextPart(DeltinScriptParser.VariableContext variable)
 {
     this.variable   = variable ?? throw new ArgumentNullException(nameof(variable));
     Range           = DocRange.GetRange(variable);
     CompletionRange = Range;
 }
        private void GetParts(ParseInfo parseInfo, Scope scope, DeltinScriptParser.ExprContext left, string op, DocRange opRange, DeltinScriptParser.ExprContext right)
        {
            // Left operator.
            if (left == null)
            {
                parseInfo.Script.Diagnostics.Error("Missing left operator.", opRange);
            }
            else
            {
                Left = parseInfo.GetExpression(scope, left);
            }

            // Right operator.
            if (right == null)
            {
                parseInfo.Script.Diagnostics.Error("Missing right operator.", opRange);
            }
            else
            {
                Right = parseInfo.GetExpression(scope, right);
            }

            Operator = op;
        }
예제 #19
0
 public TreeContextPart(DeltinScriptParser.ExprContext expression)
 {
     this.expression = expression ?? throw new ArgumentNullException(nameof(expression));
     Range           = DocRange.GetRange(expression);
     CompletionRange = Range;
 }
 public ThisAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_thisContext context)
 {
     ThisType = scope.GetThis();
     if (ThisType == null)
     {
         parseInfo.Script.Diagnostics.Error("Keyword 'this' cannot be used here.", DocRange.GetRange(context));
     }
 }
 public void Error(string message, DocRange range)
 {
     _diagnostics.Add(new Diagnostic(message, range, Diagnostic.Error));
 }
        public BaseAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_baseContext context)
        {
            CodeType thisType = scope.GetThis();

            // Syntax error if the 'base' keyword is used outside of classes.
            if (thisType == null)
            {
                parseInfo.Script.Diagnostics.Error("Keyword 'base' cannot be used here.", DocRange.GetRange(context));
            }

            // Syntax error if the current class does not extend anything.
            else if (thisType.Extends == null)
            {
                parseInfo.Script.Diagnostics.Error("The current type does not extend a class.", DocRange.GetRange(context));
            }

            else
            {
                baseType = thisType.Extends;
            }
        }
 public void Information(string message, DocRange range)
 {
     _diagnostics.Add(new Diagnostic(message, range, Diagnostic.Information));
 }
        public IsAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_isContext isContext)
        {
            // Get the expression.
            expression = parseInfo.GetExpression(scope, isContext.expr());

            // Get the type.
            if (isContext.type == null)
            {
                parseInfo.Script.Diagnostics.Error("Expected type name.", DocRange.GetRange(isContext.IS()));
            }
            else
            {
                CodeType type = parseInfo.TranslateInfo.Types.GetCodeType(isContext.type.Text, parseInfo.Script.Diagnostics, DocRange.GetRange(isContext.type));

                // Make sure the received type is a class.
                if (type != null && type is ClassType == false)
                {
                    parseInfo.Script.Diagnostics.Error("Expected a class type.", DocRange.GetRange(isContext.type));
                }
                else
                {
                    checkingIfType = (ClassType)type;
                }
            }
        }
 public CheckLambdaContext(ParseInfo parseInfo, ILambdaApplier applier, string errorMessage, DocRange range, ParameterState parameterState)
 {
     ParseInfo      = parseInfo;
     Applier        = applier;
     ErrorMessage   = errorMessage;
     Range          = range;
     ParameterState = parameterState;
 }
 public void OutputComment(FileDiagnostics diagnostics, DocRange range, string comment)
 {
     Comment = comment;
 }
예제 #27
0
 public DefinedMacro(ParseInfo parseInfo, Scope objectScope, Scope staticScope, DeltinScriptParser.Define_macroContext context, CodeType returnType)
     : base(parseInfo, context.name.Text, new LanguageServer.Location(parseInfo.Script.Uri, DocRange.GetRange(context.name)))
 {
     this.context = context;
     Static       = context.STATIC() != null;
     SetupScope(Static ? staticScope : objectScope);
     AccessLevel       = context.accessor().GetAccessLevel();
     ReturnType        = returnType;
     ExpressionToParse = context.expr();
     doesReturnValue   = true;
 }
예제 #28
0
 public VariableResolve(ParseInfo parseInfo, VariableResolveOptions options, IExpression expression, DocRange expressionRange)
     : this(parseInfo, options, expression, expressionRange, new VariableResolveErrorHandler(parseInfo.Script.Diagnostics))
 {
 }
        public static IStatement GetStatement(ParseInfo parseInfo, Scope scope, DeltinScriptParser.StatementContext statementContext)
        {
            switch (statementContext)
            {
            case DeltinScriptParser.S_defineContext define: {
                var newVar = new ScopedVariable(scope, new DefineContextHandler(parseInfo, define.define()));
                return(new DefineAction(newVar));
            }

            case DeltinScriptParser.S_methodContext method: return(new CallMethodAction(parseInfo, scope, method.method(), false, scope));

            case DeltinScriptParser.S_varsetContext varset: return(new SetVariableAction(parseInfo, scope, varset.varset()));

            case DeltinScriptParser.S_exprContext s_expr: {
                var expr = GetExpression(parseInfo, scope, s_expr.expr(), true, false);
                if (expr is ExpressionTree == false || ((ExpressionTree)expr)?.Result is IStatement == false)
                {
                    if (expr != null)
                    {
                        parseInfo.Script.Diagnostics.Error("Expressions can't be used as statements.", DocRange.GetRange(statementContext));
                    }
                    return(null);
                }
                else
                {
                    return((ExpressionTree)expr);
                }
            }

            case DeltinScriptParser.S_ifContext s_if: return(new IfAction(parseInfo, scope, s_if.@if()));

            case DeltinScriptParser.S_whileContext s_while: return(new WhileAction(parseInfo, scope, s_while.@while()));

            case DeltinScriptParser.S_forContext s_for: return(new ForAction(parseInfo, scope, s_for.@for()));

            case DeltinScriptParser.S_for_autoContext s_forAuto: return(new AutoForAction(parseInfo, scope, s_forAuto.for_auto()));

            case DeltinScriptParser.S_foreachContext s_foreach: return(new ForeachAction(parseInfo, scope, s_foreach.@foreach()));

            case DeltinScriptParser.S_returnContext s_return: return(new ReturnAction(parseInfo, scope, s_return.@return()));

            case DeltinScriptParser.S_deleteContext s_delete: return(new DeleteAction(parseInfo, scope, s_delete.delete()));

            case DeltinScriptParser.S_continueContext s_continue: return(new ContinueAction(parseInfo, DocRange.GetRange(s_continue)));

            case DeltinScriptParser.S_breakContext s_break: return(new BreakAction(parseInfo, DocRange.GetRange(s_break)));

            case DeltinScriptParser.S_switchContext s_switch: return(new SwitchAction(parseInfo, scope, s_switch.@switch()));

            case DeltinScriptParser.S_blockContext s_block: return(new BlockAction(parseInfo, scope, s_block));

            default: return(null);
            }
        }
        private void GetRuleSettings(ParseInfo parseInfo, Scope scope, RuleContext ruleContext)
        {
            RuleSetting teamContext = null, playerContext = null;
            bool        setEventType = false, setTeam = false, setPlayer = false;

            foreach (var setting in ruleContext.Settings)
            {
                // Add completion.
                switch (setting.Setting.Text)
                {
                case "Event": AddCompletion(parseInfo, setting.Dot, setting.Value, EventItems); break;

                case "Team": AddCompletion(parseInfo, setting.Dot, setting.Value, TeamItems); break;

                case "Player": AddCompletion(parseInfo, setting.Dot, setting.Value, PlayerItems); break;
                }

                // Get the value.
                if (setting.Value != null)
                {
                    var      alreadySet = new Diagnostic("The " + setting.Setting.Text + " rule setting was already set.", setting.Range, Diagnostic.Error);
                    string   name       = setting.Value.Text;
                    DocRange range      = setting.Value.Range;

                    switch (setting.Setting.Text)
                    {
                    case "Event":
                        if (setEventType)
                        {
                            parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet);
                        }
                        EventType    = GetMember <RuleEvent>("Event", name, parseInfo.Script.Diagnostics, range);
                        setEventType = true;
                        break;

                    case "Team":
                        if (setTeam)
                        {
                            parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet);
                        }
                        Team        = GetMember <Team>("Team", name, parseInfo.Script.Diagnostics, range);
                        setTeam     = true;
                        teamContext = setting;
                        break;

                    case "Player":
                        if (setPlayer)
                        {
                            parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet);
                        }
                        Player        = GetMember <PlayerSelector>("Player", name, parseInfo.Script.Diagnostics, range);
                        setPlayer     = true;
                        playerContext = setting;
                        break;

                    default:
                        parseInfo.Script.Diagnostics.Error("Expected an enumerator of type 'Event', 'Team', or 'Player'.", setting.Setting.Range);
                        break;
                    }
                }
            }

            // Set the event type to player if the event type was not set and player or team was changed.
            if (!setEventType && ((setPlayer && Player != PlayerSelector.All) || (setTeam && Team != Team.All)))
            {
                EventType = RuleEvent.OngoingPlayer;
            }

            if (setEventType && EventType == RuleEvent.OngoingGlobal)
            {
                // Syntax error if the event type is global and the team type is not default.
                if (Team != Team.All)
                {
                    parseInfo.Script.Diagnostics.Error("Can't change rule Team type with an event type of Ongoing Global.", teamContext.Range);
                }
                // Syntax error if the event type is global and the player type is not default.
                if (Player != PlayerSelector.All)
                {
                    parseInfo.Script.Diagnostics.Error("Can't change rule Player type with an event type of Ongoing Global.", playerContext.Range);
                }
            }
        }