/// <summary> /// Matches a <c>ForStatement</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>ForStatement</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>For</c>. /// </remarks> protected virtual bool MatchForStatement(out Statement statement) { statement = null; int startOffset = this.LookAheadToken.StartOffset; if (!this.Match(LuatTokenId.For)) return false; Identifier firstIdent = null; if (!this.MatchIdentifier(out firstIdent)) return false; if (this.TokenIs(this.LookAheadToken, LuatTokenId.Assignment)) { // for a = b, c, d do ... end VariableExpression firstVar = new VariableExpression( firstIdent ); ForStatement forStatement = new ForStatement(); statement = forStatement; forStatement.Iterator = firstVar as VariableExpression; if (!this.Match(LuatTokenId.Assignment)) return false; Expression start = null; if (!this.MatchExpression(out start)) return false; forStatement.Start = start; if (!this.Match(LuatTokenId.Comma)) return false; Expression end = null; if (!this.MatchExpression(out end)) return false; forStatement.End = end; if (this.TokenIs(this.LookAheadToken, LuatTokenId.Comma)) { if (!this.Match(LuatTokenId.Comma)) return false; Expression step = null; if (!this.MatchExpression(out step)) return false; forStatement.Step = step; } if (!this.Match(LuatTokenId.Do)) return false; BlockStatement body; if (!this.MatchBlock(out body)) return false; forStatement.Body = body; if (!this.Match(LuatTokenId.End)) return false; forStatement.StartOffset = startOffset; forStatement.EndOffset = this.Token.EndOffset; } else if (((this.TokenIs(this.LookAheadToken, LuatTokenId.Comma)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.In)))) { // for a,b in c,d do ... end ForInStatement forInStatement = new ForInStatement(); statement = forInStatement; forInStatement.Iterators.Add( firstIdent ); if (this.TokenIs(this.LookAheadToken, LuatTokenId.Comma)) { if (!this.Match(LuatTokenId.Comma)) return false; if (!this.MatchIdentifierList(forInStatement.Iterators)) return false; } if (!this.Match(LuatTokenId.In)) return false; if (!this.MatchExpressionList(forInStatement.Tables)) return false; if (!this.Match(LuatTokenId.Do)) return false; BlockStatement body; if (!this.MatchBlock(out body)) return false; forInStatement.Body = body; if (!this.Match(LuatTokenId.End)) return false; forInStatement.StartOffset = startOffset; forInStatement.EndOffset = this.Token.EndOffset; } else return false; return true; }
/// <summary> /// Matches a <c>Variable</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Variable</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Identifier</c>. /// </remarks> protected virtual bool MatchVariable(out Expression expression) { expression = null; Identifier identifier; if (!this.MatchIdentifier(out identifier)) return false; expression = new VariableExpression( identifier ); return true; }
private static bool CheckVariableNameInUse(VariableExpression expression, string variableName) { if (expression == null) return false; var scripts = new List<LuatScript>(); var bs = expression.FindAncestor<BlockStatement>(); while (bs != null) { foreach (var i in bs.Locals.Entries) { LuatTable table = i.Value; if (!scripts.Contains(i.Key)) scripts.Add(i.Key); foreach (var v in table.Children) { string name = v.Key; if (name == variableName) return true; } } bs = bs.FindAncestor<BlockStatement>(); } foreach (LuatScript script in scripts) { var visited = new HashSet<LuatValue>(); IEnumerable<KeyValuePair<string, LuatValue>> children = script.Table.GetChildren(ref visited); foreach (KeyValuePair<string, LuatValue> child in children) { if (child.Key == variableName) return true; } } return false; }
/// <summary> /// Matches a <c>FunctionName</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>FunctionName</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Identifier</c>. /// </remarks> protected virtual bool MatchFunctionName(out Expression expression, out bool expectsSelf) { expression = null; Identifier identifier; IToken indexToken; expectsSelf = false; if (!this.MatchIdentifier(out identifier)) return false; expression = new VariableExpression( identifier ); while (this.TokenIs(this.LookAheadToken, LuatTokenId.Dot)) { if (!this.Match(LuatTokenId.Dot)) return false; indexToken = this.Token; if (!this.MatchIdentifier(out identifier)) return false; expression = new IndexExpression( expression, indexToken, identifier ); } if (this.TokenIs(this.LookAheadToken, LuatTokenId.Colon)) { if (!this.Match(LuatTokenId.Colon)) return false; indexToken = this.Token; expectsSelf = true; if (!this.MatchIdentifier(out identifier)) return false; expression = new IndexExpression( expression, indexToken, identifier ); } return true; }
private static bool CanRenameVariable(ILuaIntellisenseDocument document, out VariableExpression expression, out List<LuatValue.IReference> definitions) { expression = null; definitions = null; if (!CanGoto(document)) return false; if (document.SyntaxEditorControl == null) return false; var se = (ActiproSoftware.SyntaxEditor.SyntaxEditor)document.SyntaxEditorControl; if ((se.SelectedView == null) || (se.SelectedView.Selection == null)) return false; expression = GetExpressionAt(se.Document, se.SelectedView.Selection.StartOffset) as VariableExpression; if (expression == null) return false; definitions = new List<LuatValue.IReference>(); foreach (LuatValue value in expression.ResolvedValues.Values) { var variable = value.As<LuatVariable>(); if (variable != null) definitions.Merge(variable.References.ToArray()); } return definitions.Count > 0; }