public IScopeable GetVariable(string name, Scope getter, FileDiagnostics diagnostics, DocRange range) { IScopeable element = null; Scope current = this; while (current != null && element == null) { element = current.Variables.FirstOrDefault(element => element.Name == name); current = current.Parent; } if (range != null && element == null) { diagnostics.Error(string.Format("The variable {0} does not exist in the {1}.", name, ErrorName), range); } if (element != null && getter != null && !getter.AccessorMatches(element)) { if (range == null) { throw new Exception(); } diagnostics.Error(string.Format("'{0}' is inaccessable due to its access level.", name), range); } return(element); }
public bool AccessorMatches(IScopeable element) { if (element.AccessLevel == AccessLevel.Public) { return(true); } bool matches = false; IterateElements(true, true, itElement => { if (element == itElement.Element) { matches = true; return(ScopeIterateAction.Stop); } if ((itElement.Container.PrivateCatch && element.AccessLevel == AccessLevel.Private) || (itElement.Container.ProtectedCatch && element.AccessLevel == AccessLevel.Protected)) { return(ScopeIterateAction.StopAfterScope); } return(ScopeIterateAction.Continue); }); return(matches); }
/// <summary> /// Adds a variable to the current scope. /// When handling variables added by the user, supply the diagnostics and range to show the syntax error at. /// When handling variables added internally, have the diagnostics and range parameters be null. An exception will be thrown instead if there is a syntax error. /// </summary> /// <param name="variable">The variable that will be added to the current scope. If the object reference is already in the direct scope, an exception will be thrown.</param> /// <param name="diagnostics">The file diagnostics to throw errors with. Should be null when adding variables internally.</param> /// <param name="range">The document range to throw errors at. Should be null when adding variables internally.</param> public void AddVariable(IScopeable variable, FileDiagnostics diagnostics, DocRange range) { if (variable == null) { throw new ArgumentNullException(nameof(variable)); } if (Variables.Contains(variable)) { throw new Exception("variable reference is already in scope."); } if (IsVariable(variable.Name)) { string message = string.Format("A variable of the name {0} was already defined in this scope.", variable.Name); if (diagnostics != null && range != null) { diagnostics.Error(message, range); } else { throw new Exception(message); } } else { Variables.Add(variable); } }
/// <summary>Adds a variable to the scope that already belongs to another scope.</summary> public void CopyVariable(IScopeable variable) { if (variable == null) { throw new ArgumentNullException(nameof(variable)); } if (!Variables.Contains(variable)) { Variables.Add(variable); } }
public void In(IScopeable var) { //if (!FullVarCollection().Any(v => var.Name == v.Name)) if (IsAlreadyDefined(var.Name) && var.Node != null) { throw SyntaxErrorException.AlreadyDefined(var.Name, var.Node.Location); } else { InScope.Add(var); } }
private T GetScopeable <T>(string name) where T : IScopeable { IScopeable var = null; ScopeGroup checkGroup = this; while (var == null && checkGroup != null) { var = checkGroup.InScope.FirstOrDefault(v => v is T && v.Name == name); checkGroup = checkGroup.Parent; } return((T)var); }
private T GetScopeable <T>(ScopeGroup getter, string name) where T : IScopeable { bool publicOnly = getter.Root() != Root(); IScopeable var = null; ScopeGroup checkGroup = this; while (var == null && checkGroup != null) { var = checkGroup.InScope.FirstOrDefault(v => v is T && v.Name == name && (!publicOnly || v.AccessLevel == AccessLevel.Public)); checkGroup = checkGroup.Parent; } return((T)var); }
public bool ScopeContains(IScopeable scopeable, Scope getter) { bool found = false; IterateElements(true, true, iterate => { if (iterate.Element == scopeable) { found = true; return(ScopeIterateAction.Stop); } return(ScopeIterateAction.Continue); }); return(found); }
public bool ScopeContains(IScopeable element) { // Variable if (element is IVariable variable) { return(ScopeContains(variable)); } // Function else if (element is IMethod function) { return(ScopeContains(function)); } else { throw new NotImplementedException(); } }
public IScopeable GetVariable(string name, FileDiagnostics diagnostics, DocRange range) { IScopeable element = null; Scope current = this; while (current != null && element == null) { element = current.Variables.FirstOrDefault(element => element.Name == name); current = current.Parent; } if (range != null && element == null) { diagnostics.Error(string.Format("The variable {0} does not exist in the {1}.", name, ErrorName), range); } return(element); }
public bool Conflicts(IScopeable scopeable, bool variables = true, bool functions = true) { bool conflicts = false; IterateElements(variables, functions, action => { // If the element name matches, set conflicts to true then stop iterating. if (scopeable.Name == action.Element.Name) { if (functions || action.Element is MethodGroup == false) { conflicts = true; } return(ScopeIterateAction.Stop); } return(action.Container.CatchConflict ? ScopeIterateAction.StopAfterScope : ScopeIterateAction.Continue); }, scope => { return(scope.CatchConflict ? ScopeIterateAction.StopAfterScope : ScopeIterateAction.Continue); }); return(conflicts); }
private bool WasScopedAtPosition(IScopeable element, Pos pos, Scope getter) { return((pos == null || element.DefinedAt == null || element.WholeContext || element.DefinedAt.range.start <= pos) && (getter == null || getter.AccessorMatches(element))); }
private static bool WasScopedAtPosition(IScopeable element, Pos pos) { return(pos == null || element.DefinedAt == null || element.WholeContext || element.DefinedAt.range.start <= pos); }
public static IExpression GetVariable(ParseInfo parseInfo, Scope scope, Scope getter, DeltinScriptParser.VariableContext variableContext, bool selfContained) { string variableName = variableContext.PART().GetText(); DocRange variableRange = DocRange.GetRange(variableContext.PART()); var type = parseInfo.TranslateInfo.GetCodeType(variableName, null, null); if (type != null) { if (selfContained) { parseInfo.Script.Diagnostics.Error("Types can't be used as expressions.", variableRange); } if (variableContext.array() != null) { parseInfo.Script.Diagnostics.Error("Indexers cannot be used with types.", DocRange.GetRange(variableContext.array())); } type.Call(parseInfo.Script, variableRange); return(type); } IScopeable element = scope.GetVariable(variableName, getter, parseInfo.Script.Diagnostics, variableRange); if (element == null) { return(null); } if (element is ICallable) { ((ICallable)element).Call(parseInfo.Script, variableRange); } if (element is IApplyBlock) { parseInfo.CurrentCallInfo?.Call((IApplyBlock)element, variableRange); } if (element is IIndexReferencer var) { IExpression[] index; if (variableContext.array() == null) { index = new IExpression[0]; } else { index = new IExpression[variableContext.array().expr().Length]; for (int i = 0; i < index.Length; i++) { index[i] = GetExpression(parseInfo, getter, variableContext.array().expr(i)); } } return(new CallVariableAction(var, index)); } else if (element is ScopedEnumMember) { return((ScopedEnumMember)element); } else if (element is DefinedEnumMember) { return((DefinedEnumMember)element); } else if (element is MacroVar) { return((MacroVar)element); } else { throw new NotImplementedException(); } }
public ClassElement(IScopeable scopeable, bool isInstance) { Scopeable = scopeable; IsInstance = isInstance; }
public void AddNativeVariable(IScopeable variable) { AddVariable(variable, null, null); }
public ScopeIterate(Scope container, IScopeable element, bool accessorMatches) { Container = container; Element = element; AccessorMatches = accessorMatches; }
public bool IsAlreadyInScope(IScopeable scopeable) => Variables.Contains(scopeable);