Exemplo n.º 1
0
        public void Validate_Get_expr_yields_no_error_for_defined_variable()
        {
            // Arrange
            //
            // This is the method being referred to. The expression below roughly matches "Foo.to_string", where
            // Foo is a defined Perlang class.
            var name       = new Token(TokenType.IDENTIFIER, "to_string", null, -1);
            var identifier = new Expr.Identifier(name);
            var getExpr    = new Expr.Get(identifier, name);

            var bindings = new Dictionary <Expr, Binding>
            {
                { identifier, new ClassBinding(identifier, new PerlangClass("Foo", new List <Stmt.Function>())) }
            };

            var typeValidationErrors = new List <TypeValidationError>();
            var warnings             = new List <CompilerWarning>();

            // Act
            TypeValidator.Validate(
                new List <Stmt> {
                new Stmt.ExpressionStmt(getExpr)
            },
                error => typeValidationErrors.Add(error),
                expr => bindings[expr],
                warning => warnings.Add(warning)
                );

            // Assert
            Assert.Empty(typeValidationErrors);
            Assert.Empty(warnings);
        }
Exemplo n.º 2
0
        public void Validate_Get_expr_yields_expected_error_for_undefined_variable()
        {
            // Arrange
            var name       = new Token(TokenType.IDENTIFIER, "foo", null, -1);
            var identifier = new Expr.Identifier(name);
            var getExpr    = new Expr.Get(identifier, name);

            var bindings = new Dictionary <Expr, Binding>
            {
                // A null TypeReference here is the condition that is expected to lead to an "undefined variable" error.
                { identifier, new VariableBinding(typeReference: null, 0, identifier) }
            };

            var typeValidationErrors = new List <TypeValidationError>();
            var warnings             = new List <CompilerWarning>();

            // Act
            TypeValidator.Validate(
                new List <Stmt> {
                new Stmt.ExpressionStmt(getExpr)
            },
                error => typeValidationErrors.Add(error),
                expr => bindings[expr],
                warning => warnings.Add(warning)
                );

            // Assert
            Assert.Single(typeValidationErrors);
            Assert.Matches(typeValidationErrors.Single().Message, "Undefined identifier 'foo'");

            Assert.Empty(warnings);
        }
Exemplo n.º 3
0
        public void Validate_Call_expr_does_something_useful()
        {
            // Arrange
            var name       = new Token(TokenType.IDENTIFIER, "to_string", null, 1);
            var identifier = new Expr.Identifier(name);
            var get        = new Expr.Get(identifier, name);
            var paren      = new Token(TokenType.RIGHT_PAREN, ")", null, 1);
            var callExpr   = new Expr.Call(get, paren, new List <Expr>());
            var bindings   = new Dictionary <Expr, Binding>
            {
                { identifier, new NativeClassBinding(identifier, typeof(string)) }
            };

            var typeValidationErrors = new List <TypeValidationError>();
            var warnings             = new List <CompilerWarning>();

            // Act
            TypeValidator.Validate(
                new List <Stmt> {
                new Stmt.ExpressionStmt(callExpr)
            },
                error => typeValidationErrors.Add(error),
                expr => bindings[expr],
                warning => warnings.Add(warning)
                );

            // Assert
            Assert.Empty(typeValidationErrors);
            Assert.Empty(warnings);
        }
Exemplo n.º 4
0
        public VoidObject VisitIdentifierExpr(Expr.Identifier expr)
        {
            // Note: providing the defaultValue in the TryGetObjectValue() call here is critical, since we must be able
            // to distinguish between "set to null" and "not set at all".
            if (!IsEmpty(scopes) &&
                scopes.Last().TryGetObjectValue(expr.Name.Lexeme, VariableBindingFactory.None) == null)
            {
                nameResolutionErrorHandler(new NameResolutionError("Cannot read local variable in its own initializer.", expr.Name));
            }

            ResolveLocalOrGlobal(expr, expr.Name);

            return(VoidObject.Void);
        }
Exemplo n.º 5
0
 public string VisitIdentifierExpr(Expr.Identifier expr)
 {
     return(expr.Name.Lexeme);
 }