1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "tools/gn/input_file.h" 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "tools/gn/parse_tree.h" 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "tools/gn/scope.h" 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "tools/gn/test_with_scope.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 11effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(ParseTree, Accessor) { 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch TestWithScope setup; 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Make a pretend parse node with proper tracking that we can blame for the 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // given value. 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch InputFile input_file(SourceFile("//foo")); 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Token base_token(Location(&input_file, 1, 1, 1), Token::IDENTIFIER, "a"); 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Token member_token(Location(&input_file, 1, 1, 1), Token::IDENTIFIER, "b"); 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AccessorNode accessor; 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch accessor.set_base(base_token); 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<IdentifierNode> member_identifier( 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new IdentifierNode(member_token)); 25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch accessor.set_member(member_identifier.Pass()); 26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // The access should fail because a is not defined. 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Err err; 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Value result = accessor.Execute(setup.scope(), &err); 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(err.has_error()); 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(Value::NONE, result.type()); 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Define a as a Scope. It should still fail because b isn't defined. 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch err = Err(); 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch setup.scope()->SetValue("a", 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Value(NULL, scoped_ptr<Scope>(new Scope(setup.scope()))), NULL); 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = accessor.Execute(setup.scope(), &err); 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(err.has_error()); 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(Value::NONE, result.type()); 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Define b, accessor should succeed now. 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const int64 kBValue = 42; 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch err = Err(); 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch setup.scope()->GetMutableValue("a", false)->scope_value()->SetValue( 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "b", Value(NULL, kBValue), NULL); 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = accessor.Execute(setup.scope(), &err); 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_FALSE(err.has_error()); 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_EQ(Value::INTEGER, result.type()); 49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(kBValue, result.int_value()); 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(ParseTree, BlockUnusedVars) { 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestWithScope setup; 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Printing both values should be OK. 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestParseInput input_all_used( 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "{\n" 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " a = 12\n" 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " b = 13\n" 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " print(\"$a $b\")\n" 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "}"); 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(input_all_used.has_error()); 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Err err; 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_all_used.parsed()->Execute(setup.scope(), &err); 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(err.has_error()); 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Skipping one should throw an unused var error. 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestParseInput input_unused( 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "{\n" 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " a = 12\n" 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " b = 13\n" 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " print(\"$a\")\n" 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "}"); 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(input_unused.has_error()); 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_unused.parsed()->Execute(setup.scope(), &err); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(err.has_error()); 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Also verify that the unused variable has the correct origin set. The 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // origin will point to the value assigned to the variable (in this case, the 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // "13" assigned to "b". 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(3, err.location().line_number()); 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(7, err.location().char_offset()); 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST(ParseTree, OriginForDereference) { 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) TestWithScope setup; 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) TestParseInput input( 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "a = 6\n" 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "get_target_outputs(a)"); 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(input.has_error()); 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Err err; 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) input.parsed()->Execute(setup.scope(), &err); 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(err.has_error()); 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The origin for the "not a string" error message should be where the value 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // was dereferenced (the "a" on the second line). 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(2, err.location().line_number()); 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(20, err.location().char_offset()); 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 104