diff options
Diffstat (limited to 'examples')
62 files changed, 1980 insertions, 0 deletions
diff --git a/examples/cpp/BUILD b/examples/cpp/BUILD new file mode 100644 index 0000000000..195bbb3d25 --- /dev/null +++ b/examples/cpp/BUILD @@ -0,0 +1,25 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "hello-lib", + srcs = ["hello-lib.cc"], + hdrs = ["hello-lib.h"], +) + +cc_binary( + name = "hello-world", + srcs = ["hello-world.cc"], + deps = [":hello-lib"], +) + +cc_test( + name = "hello-success_test", + srcs = ["hello-world.cc"], + deps = [":hello-lib"], +) + +cc_test( + name = "hello-fail_test", + srcs = ["hello-fail.cc"], + deps = [":hello-lib"], +) diff --git a/examples/cpp/README.md b/examples/cpp/README.md new file mode 100644 index 0000000000..fba714321c --- /dev/null +++ b/examples/cpp/README.md @@ -0,0 +1,4 @@ +C++ Examples +============ + +These examples demonstrate building C++ binaries, libraries, and tests. diff --git a/examples/cpp/hello-fail.cc b/examples/cpp/hello-fail.cc new file mode 100644 index 0000000000..5b561cb0ce --- /dev/null +++ b/examples/cpp/hello-fail.cc @@ -0,0 +1,22 @@ +#include "examples/cpp/hello-lib.h" + +#include <string> + +using hello::HelloLib; +using std::string; + +/** + * This is a fake test that prints "Hello barf" and then exits with exit code 1. + * If run as a test (cc_test), the non-0 exit code indicates to Bazel that the + * "test" has failed. + */ +int main(int argc, char** argv) { + HelloLib lib; + string thing = "barf"; + if (argc > 1) { + thing = argv[1]; + } + + lib.greet(thing); + return 1; +} diff --git a/examples/cpp/hello-lib.cc b/examples/cpp/hello-lib.cc new file mode 100644 index 0000000000..8e40921cee --- /dev/null +++ b/examples/cpp/hello-lib.cc @@ -0,0 +1,21 @@ +#include "examples/cpp/hello-lib.h" + +#include <iostream> + +using std::cout; +using std::endl; +using std::string; + +namespace hello { + +HelloLib::HelloLib() : HelloLib("Hello") { +} + +HelloLib::HelloLib(const string& greeting) : greeting_(new string(greeting)) { +} + +void HelloLib::greet(const string& thing) { + cout << *greeting_ << " " << thing << endl; +} + +} // namespace hello diff --git a/examples/cpp/hello-lib.h b/examples/cpp/hello-lib.h new file mode 100644 index 0000000000..555d177936 --- /dev/null +++ b/examples/cpp/hello-lib.h @@ -0,0 +1,23 @@ +#ifndef EXAMPLES_CPP_HELLO_LIB_H_ +#define EXAMPLES_CPP_HELLO_LIB_H_ + +#include <string> +#include <memory> + +namespace hello { + +class HelloLib { + public: + HelloLib(); + + explicit HelloLib(const std::string &greeting); + + void greet(const std::string &thing); + + private: + std::unique_ptr<const std::string> greeting_; +}; + +} // namespace hello + +#endif // EXAMPLES_CPP_HELLO_LIB_H_ diff --git a/examples/cpp/hello-world.cc b/examples/cpp/hello-world.cc new file mode 100644 index 0000000000..be435c3256 --- /dev/null +++ b/examples/cpp/hello-world.cc @@ -0,0 +1,26 @@ +#include "examples/cpp/hello-lib.h" + +#include <string> + +using hello::HelloLib; +using std::string; + +/** + * This prints "Hello world". If it is run with arguments, it will use the first + * argument instead of "world". Build and run //examples/cpp:hello-world to see + * this program in action. + * + * This file does double-duty as a "test." It is a cc_binary, so it can also be + * compiled as a cc_test and Bazel will decide on whether it passed or failed + * based on exit code (which is always 0 here, so the test "passes"). See + * hello-fail.cc for an example of making a test fail. + */ +int main(int argc, char** argv) { + HelloLib lib("Hello"); + string thing = "world"; + if (argc > 1) { + thing = argv[1]; + } + lib.greet(thing); + return 0; +} diff --git a/examples/gen/BUILD b/examples/gen/BUILD new file mode 100644 index 0000000000..988fa8b7de --- /dev/null +++ b/examples/gen/BUILD @@ -0,0 +1,14 @@ +package(default_visibility = ["//visibility:public"]) + +genquery( + name = "genquery", + expression = "deps(//tools/defaults:jdk)", + scope = ["//tools/defaults:jdk"], +) + +genrule( + name = "genrule", + srcs = [":genquery"], + outs = ["genrule.txt"], + cmd = "cat $(SRCS) > $@", +) diff --git a/examples/go/BUILD b/examples/go/BUILD new file mode 100644 index 0000000000..dd0846110c --- /dev/null +++ b/examples/go/BUILD @@ -0,0 +1,14 @@ +# See README.md for instructions on how to use these rules. + +package(default_visibility = ["//visibility:public"]) + +load("/tools/build_rules/go_rules", "go_library", "go_binary") + +go_binary( + name = "fib", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + deps = ["//examples/go/lib1"], +) diff --git a/examples/go/README.md b/examples/go/README.md new file mode 100644 index 0000000000..69bcc4c664 --- /dev/null +++ b/examples/go/README.md @@ -0,0 +1,121 @@ + +Go rules +-------- + +The files here demonstrate how to use the rules for Go supplied under +`//tools/build_rules:go_rules.bzl`. The rules should be considered +experimental. They support: + + * libraries + * binaries + * tests + +They currently do not support: + + * coverage + * race detector + * multiple target configurations + * //+build tags + * C/C++ interoperation (cgo, swig etc.) + + +Testing +------- + +Setup a symlink to the Go installation you wish to use, + + ln -s /usr/lib/golang/ tools/go/go_root + +or + + ln -s $(go env GOROOT) tools/go/go_root + +To build something, run + + bazel build examples/go/... + +To run a test, run + + bazel test --test_arg=--test.v examples/go/lib1:lib1_test + + +Writing BUILD rules +------------------- + +In the bazel model of compiling Go, each directory can hold multiple +packages, rather than just one in the standard "go" tool. Suppose you +have + + dir/f.go: + + package p + func F() {} + +then in the BUILD file could say + + go_library( + name = "q", + srcs = ["f.go"]) + +and you import it with its Bazel name, + + import "dir/p/q" + +this add the declared package name as namespace, i.e., it is +equivalent to + + import p "dir/p/q" + +so you use it as follows + + import "dir/p/q" + main() { + p.F() + } + + +Writing tests +------------- + +For tests, you should create a separate target, + + go_test( + name = "q_test", + srcs = [ "f_test.go" ], + deps = [ ":q" ]) + +if the test code is in the same package as the library under test +(e.g., because you are testing private parts of the library), you should +use the `library` attribute, + + go_test( + name = "q_test", + srcs = [ "f_test.go" ], + library = ":q" ) + +This causes the test and the library under test to be compiled +together. + + +FAQ +--- + +# Why does this not follow the external Go conventions? + +These rules were inspired on Google's internal Go rules, which work +like this. For Bazel, these make more sense, because directories in +Bazel do not correspond to single targets. + + +# Do I have to specify dependencies twice? + +Yes, once in the BUILD file, once in the source file. Bazel does not +examine file contents, so it cannot infer the dependencies. It is +possible to generate the BUILD file from the Go sources through a +separate program, though. + + +Disclaimer +---------- + +These rules are not supported by Google's Go team. diff --git a/examples/go/fib.go b/examples/go/fib.go new file mode 100644 index 0000000000..43d8a499ba --- /dev/null +++ b/examples/go/fib.go @@ -0,0 +1,11 @@ +package main + +import ( + "fmt" + + "examples/go/lib1/lib1" +) + +func main() { + fmt.Println("Fib(5):", lib1.Fib(5)) +} diff --git a/examples/go/lib1/BUILD b/examples/go/lib1/BUILD new file mode 100644 index 0000000000..fb400772ef --- /dev/null +++ b/examples/go/lib1/BUILD @@ -0,0 +1,24 @@ +package(default_visibility = ["//visibility:public"]) + +load("/tools/build_rules/go_rules", "go_library", "go_binary", "go_test") + +go_library( + name = "lib1", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), +) + +go_test( + name = "lib1_test", + srcs = [ + "lib1_test.go", + ], + library = ":lib1", +) + +go_test( + name = "fail_test", + srcs = ["fail_test.go"], +) diff --git a/examples/go/lib1/fail_test.go b/examples/go/lib1/fail_test.go new file mode 100644 index 0000000000..5ef41a3b4d --- /dev/null +++ b/examples/go/lib1/fail_test.go @@ -0,0 +1,9 @@ +package fail + +import ( + "testing" +) + +func TestFail(t *testing.T) { + t.Fatal("I am failing.") +} diff --git a/examples/go/lib1/lib1.go b/examples/go/lib1/lib1.go new file mode 100644 index 0000000000..f42494770d --- /dev/null +++ b/examples/go/lib1/lib1.go @@ -0,0 +1,9 @@ +package lib1 + +func Fib(n int) int { + if n < 2 { + return 1 + } + + return Fib(n-1) + Fib(n-2) +} diff --git a/examples/go/lib1/lib1_test.go b/examples/go/lib1/lib1_test.go new file mode 100644 index 0000000000..8eb88a0aca --- /dev/null +++ b/examples/go/lib1/lib1_test.go @@ -0,0 +1,14 @@ +package lib1 + +import ( + "testing" +) + +func TestFib(t *testing.T) { + got := Fib(5) + want := 8 + + if got != want { + t.Fatalf("got %d want %d", got, want) + } +} diff --git a/examples/java-native/README.md b/examples/java-native/README.md new file mode 100644 index 0000000000..fb37462bf3 --- /dev/null +++ b/examples/java-native/README.md @@ -0,0 +1,4 @@ +Java Examples +============= + +This directory contains examples for Java language rules. diff --git a/examples/java-native/src/main/java/com/example/myproject/BUILD b/examples/java-native/src/main/java/com/example/myproject/BUILD new file mode 100644 index 0000000000..717625343b --- /dev/null +++ b/examples/java-native/src/main/java/com/example/myproject/BUILD @@ -0,0 +1,24 @@ +package(default_visibility = ["//visibility:public"]) + +java_binary( + name = "hello-world", + main_class = "com.example.myproject.Greeter", + runtime_deps = [":hello-lib"], +) + +java_library( + name = "hello-lib", + srcs = glob(["*.java"]), +) + +java_binary( + name = "hello-resources", + main_class = "com.example.myproject.Greeter", + runtime_deps = [":custom-greeting"], +) + +java_library( + name = "custom-greeting", + srcs = ["Greeter.java"], + resources = ["//examples/java-native/src/main/resources:greeting"], +) diff --git a/examples/java-native/src/main/java/com/example/myproject/Greeter.java b/examples/java-native/src/main/java/com/example/myproject/Greeter.java new file mode 100644 index 0000000000..4123f2e202 --- /dev/null +++ b/examples/java-native/src/main/java/com/example/myproject/Greeter.java @@ -0,0 +1,49 @@ +package com.example.myproject; + +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Scanner; + +/** + * Prints a greeting which can be customized by building with resources and/or passing in command- + * line arguments. + * + * <p>Building and running this file will print "Hello world". Build and run the + * //examples/java-native/src/main/java/com/example/myproject:hello-world target to demonstrate + * this.</p> + * + * <p>If this is built with a greeting.txt resource included, it will replace "Hello" with the + * contents of greeting.txt. The + * //examples/java-native/src/main/java/com/example/myproject:hello-resources target demonstrates + * this.</p> + * + * <p>If arguments are passed to the binary on the command line, the first argument will replace + * "world" in the output. See //examples/java-native/src/test/java/com/example/myproject:hello's + * argument test.</p> + */ +public class Greeter { + static PrintStream out = System.out; + + public static String convertStreamToString(InputStream is) throws Exception { + try (Scanner s = new Scanner(is)) { + s.useDelimiter("\n"); + return s.hasNext() ? s.next() : ""; + } + } + + public void hello(String obj) throws Exception { + String greeting = "Hello"; + InputStream stream = Greeter.class.getResourceAsStream( + "/examples/java-native/src/main/resources/greeting.txt"); + if (stream != null) { + greeting = convertStreamToString(stream); + } + out.println(greeting + " " + obj); + } + + public static void main(String... args) throws Exception { + Greeter g = new Greeter(); + String obj = args.length > 0 ? args[0] : "world"; + g.hello(obj); + } +} diff --git a/examples/java-native/src/main/resources/BUILD b/examples/java-native/src/main/resources/BUILD new file mode 100644 index 0000000000..8347a3555a --- /dev/null +++ b/examples/java-native/src/main/resources/BUILD @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "greeting", + srcs = ["greeting.txt"], +) diff --git a/examples/java-native/src/main/resources/greeting.txt b/examples/java-native/src/main/resources/greeting.txt new file mode 100644 index 0000000000..09170083fc --- /dev/null +++ b/examples/java-native/src/main/resources/greeting.txt @@ -0,0 +1 @@ +Bye diff --git a/examples/java-native/src/test/java/com/example/myproject/BUILD b/examples/java-native/src/test/java/com/example/myproject/BUILD new file mode 100644 index 0000000000..838107650c --- /dev/null +++ b/examples/java-native/src/test/java/com/example/myproject/BUILD @@ -0,0 +1,33 @@ +java_test( + name = "hello", + srcs = ["TestHello.java"], + deps = [ + "//examples/java-native/src/main/java/com/example/myproject:hello-lib", + "//third_party:junit4", + ], +) + +java_test( + name = "custom", + srcs = ["TestCustomGreeting.java"], + deps = [ + "//examples/java-native/src/main/java/com/example/myproject:custom-greeting", + "//third_party:junit4", + ], +) + +java_test( + name = "fail", + srcs = ["Fail.java"], + deps = ["//third_party:junit4"], +) + +# This attempts to run TestCustomGreeting.java without any resources, so fails. +java_test( + name = "resource-fail", + srcs = glob(["Test*.java"]), + deps = [ + "//examples/java-native/src/main/java/com/example/myproject:hello-lib", + "//third_party:junit4", + ], +) diff --git a/examples/java-native/src/test/java/com/example/myproject/Fail.java b/examples/java-native/src/test/java/com/example/myproject/Fail.java new file mode 100644 index 0000000000..7b947c6e96 --- /dev/null +++ b/examples/java-native/src/test/java/com/example/myproject/Fail.java @@ -0,0 +1,14 @@ +package com.example.myproject; + +import org.junit.Assert; +import org.junit.Test; + +/** + * A test that always fails. + */ +public class Fail { + @Test + public void testFail() { + Assert.fail("This is an expected test failure."); + } +} diff --git a/examples/java-native/src/test/java/com/example/myproject/TestCustomGreeting.java b/examples/java-native/src/test/java/com/example/myproject/TestCustomGreeting.java new file mode 100644 index 0000000000..f14b7d234a --- /dev/null +++ b/examples/java-native/src/test/java/com/example/myproject/TestCustomGreeting.java @@ -0,0 +1,32 @@ +package com.example.myproject; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; + +/** + * Tests using a resource file to replace "Hello" in the output. + */ +public class TestCustomGreeting { + + @Test + public void testNoArgument() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Greeter.out = new PrintStream(out); + Greeter.main(); + assertEquals("Bye world\n", new String(out.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testWithArgument() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Greeter.out = new PrintStream(out); + Greeter.main("toto"); + assertEquals("Bye toto\n", new String(out.toByteArray(), StandardCharsets.UTF_8)); + } + +} diff --git a/examples/java-native/src/test/java/com/example/myproject/TestHello.java b/examples/java-native/src/test/java/com/example/myproject/TestHello.java new file mode 100644 index 0000000000..d50e6e503f --- /dev/null +++ b/examples/java-native/src/test/java/com/example/myproject/TestHello.java @@ -0,0 +1,35 @@ +package com.example.myproject; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; + +/** + * Tests different numbers of arguments to main(). + * + * <p>With an empty args array, {@link Greeter} should print "Hello world". If there are one or more + * args, {@link Greeter} should print "Hello <arg[0]>".</p> + */ +public class TestHello { + + @Test + public void testNoArgument() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Greeter.out = new PrintStream(out); + Greeter.main(); + assertEquals("Hello world\n", new String(out.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testWithArgument() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Greeter.out = new PrintStream(out); + Greeter.main("toto"); + assertEquals("Hello toto\n", new String(out.toByteArray(), StandardCharsets.UTF_8)); + } + +} diff --git a/examples/java-skylark/README.md b/examples/java-skylark/README.md new file mode 100644 index 0000000000..970a859f54 --- /dev/null +++ b/examples/java-skylark/README.md @@ -0,0 +1,7 @@ +Skylark Java Examples +===================== + +Use the native Java rules (see the examples in +_base_workspace/examples/java-native_) for building Java, not these. These +files are examples of how Skylark rules can be used (see +_tools/build_rules/java_rules_skylark.bzl_ for the rule definitions). diff --git a/examples/java-skylark/src/main/java/com/example/myproject/BUILD b/examples/java-skylark/src/main/java/com/example/myproject/BUILD new file mode 100644 index 0000000000..10ca2d440d --- /dev/null +++ b/examples/java-skylark/src/main/java/com/example/myproject/BUILD @@ -0,0 +1,21 @@ +load("/tools/build_rules/java_rules_skylark", "java_library", "java_binary", "java_test") + +package(default_visibility = ["//visibility:public"]) + +java_binary( + name = "hello-world", + srcs = ["Greeter.java"], + main_class = "com.example.myproject.Greeter", +) + +java_binary( + name = "hello-data", + main_class = "com.example.myproject.Greeter", + deps = [":hello-lib"], +) + +java_library( + name = "hello-lib", + srcs = ["Greeter.java"], + data = ["//examples/java-skylark/src/main/resources:greeting"], +) diff --git a/examples/java-skylark/src/main/java/com/example/myproject/Greeter.java b/examples/java-skylark/src/main/java/com/example/myproject/Greeter.java new file mode 100644 index 0000000000..b4d8516dc9 --- /dev/null +++ b/examples/java-skylark/src/main/java/com/example/myproject/Greeter.java @@ -0,0 +1,45 @@ +package com.example.myproject; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Scanner; + +/** + * Prints a greeting which can be customized by building with data and/or passing in command- + * line arguments. + */ +public class Greeter { + static PrintStream out = System.out; + + public static String getRunfiles() { + String path = System.getenv("JAVA_RUNFILES"); + if (path == null) { + path = System.getenv("TEST_SRCDIR"); + } + return path; + } + + public static String convertStreamToString(InputStream is) throws Exception { + Scanner s = new Scanner(is).useDelimiter("\n"); + return s.hasNext() ? s.next() : ""; + } + + public void hello(String obj) throws Exception { + String greeting = "Hello"; + try { + String greetFile = getRunfiles() + "/examples/java-skylark/src/main/resources/greeting.txt"; + greeting = convertStreamToString(new FileInputStream(greetFile)); + } catch (FileNotFoundException e) { + // use default. + } + out.println(greeting + " " + obj); + } + + public static void main(String... args) throws Exception { + Greeter g = new Greeter(); + String obj = args.length > 0 ? args[0] : "world"; + g.hello(obj); + } +}; diff --git a/examples/java-skylark/src/main/resources/BUILD b/examples/java-skylark/src/main/resources/BUILD new file mode 100644 index 0000000000..8347a3555a --- /dev/null +++ b/examples/java-skylark/src/main/resources/BUILD @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "greeting", + srcs = ["greeting.txt"], +) diff --git a/examples/java-skylark/src/main/resources/greeting.txt b/examples/java-skylark/src/main/resources/greeting.txt new file mode 100644 index 0000000000..17654db5a1 --- /dev/null +++ b/examples/java-skylark/src/main/resources/greeting.txt @@ -0,0 +1 @@ +Heyo diff --git a/examples/java-skylark/src/test/java/com/example/myproject/BUILD b/examples/java-skylark/src/test/java/com/example/myproject/BUILD new file mode 100644 index 0000000000..36c4cc3a67 --- /dev/null +++ b/examples/java-skylark/src/test/java/com/example/myproject/BUILD @@ -0,0 +1,16 @@ +load("/tools/build_rules/java_rules_skylark", "java_test") + +java_test( + name = "pass", + srcs = ["TestHello.java"], + deps = [ + "//examples/java-skylark/src/main/java/com/example/myproject:hello-lib", + "//third_party:junit4-skylark", + ], +) + +java_test( + name = "fail", + srcs = ["Fail.java"], + main_class = "com.example.myproject.Fail", +) diff --git a/examples/java-skylark/src/test/java/com/example/myproject/Fail.java b/examples/java-skylark/src/test/java/com/example/myproject/Fail.java new file mode 100644 index 0000000000..079e1e9f04 --- /dev/null +++ b/examples/java-skylark/src/test/java/com/example/myproject/Fail.java @@ -0,0 +1,7 @@ +package com.example.myproject; + +class Fail { + public static void main(String []args) { + System.exit(1); + } +} diff --git a/examples/java-skylark/src/test/java/com/example/myproject/TestHello.java b/examples/java-skylark/src/test/java/com/example/myproject/TestHello.java new file mode 100644 index 0000000000..d50e6e503f --- /dev/null +++ b/examples/java-skylark/src/test/java/com/example/myproject/TestHello.java @@ -0,0 +1,35 @@ +package com.example.myproject; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; + +/** + * Tests different numbers of arguments to main(). + * + * <p>With an empty args array, {@link Greeter} should print "Hello world". If there are one or more + * args, {@link Greeter} should print "Hello <arg[0]>".</p> + */ +public class TestHello { + + @Test + public void testNoArgument() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Greeter.out = new PrintStream(out); + Greeter.main(); + assertEquals("Hello world\n", new String(out.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testWithArgument() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Greeter.out = new PrintStream(out); + Greeter.main("toto"); + assertEquals("Hello toto\n", new String(out.toByteArray(), StandardCharsets.UTF_8)); + } + +} diff --git a/examples/objc/BUILD b/examples/objc/BUILD new file mode 100644 index 0000000000..0499d61258 --- /dev/null +++ b/examples/objc/BUILD @@ -0,0 +1,106 @@ +# Copyright 2015 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +objc_binary( + name = "PrenotCalculator", + srcs = [ + "PrenotCalculator/main.m", + ], + infoplist = "PrenotCalculator/PrenotCalculator-Info.plist", + visibility = ["//visibility:public"], + deps = [ + ":PrenotCalculatorClasses", + ], +) + +objc_library( + name = "PrenotCalculatorClasses", + srcs = [ + "PrenotCalculator/AppDelegate.m", + "PrenotCalculator/CalculatedValues.m", + "PrenotCalculator/CalculatorViewController.m", + "PrenotCalculator/CoreData.m", + "PrenotCalculator/Equation.m", + "PrenotCalculator/Literal.m", + "PrenotCalculator/ValuesViewController.m", + ], + hdrs = glob( + ["**/*.h"], + exclude = ["PrenotCalculator/Expression.h"], + ), + bundles = [":PrenotCalculatorResources"], + sdk_frameworks = ["CoreData"], + xibs = ["PrenotCalculator/CalculatorViewController.xib"], + deps = [ + ":CoreDataResources", + ":ExpressionPrebuilt", + ], +) + +# A prebuilt library that contains multiple architectures. +# Currently compiled for: i386, x86_64, armv7. +objc_import( + name = "ExpressionPrebuilt", + hdrs = ["PrenotCalculator/Expression.h"], + archives = [ + "expression_prebuilt.a", + ], +) + +# Don't use this directly, instead use it to construct ExpressionPrebuilt and +# depend on that instead. Instructions: +# Build using the following command repeatedly with the desired CPU values: +# bazel build --ios_cpu=<cpu> examples/objc/PrenotCalculator:ExpressionClasses +# and combining the resulting .a's (copied after each bazel build) using lipo: +# /usr/bin/lipo -create expression_i386.a expression_armv7.a -output expression_prebuilt.a +objc_library( + name = "ExpressionClasses", + srcs = [ + "PrenotCalculator/Expression.m", + ], + hdrs = ["PrenotCalculator/Expression.h"], +) + +objc_bundle_library( + name = "PrenotCalculatorResources", + resources = glob(["PrenotCalculator/Resources/**"]), +) + +objc_library( + name = "CoreDataResources", + datamodels = glob(["PrenotCalculator/DataModel.xcdatamodeld/**"]), +) + +# If instruments is supported this genrule should *not timeout* and it should +# produce a screenshot of the PrenotCalculator.ipa in ~ few seconds. +genrule( + name = "PrenotCalculatorInstruments", + srcs = [":PrenotCalculator.ipa"], + outs = ["hello_instruments.png"], + cmd = + # This command expects the PrenotCalculator.ipa as input then unzips + # it into a temporary directory, creates a .js script on the fly + # that captures a screenshot, and finally invokes /usr/bin/instruments + # with the former as arguments. + "unzip -q $(location :PrenotCalculator.ipa) -d $${TMPDIR} ; " + + "echo 'UIATarget.localTarget().delay(5); UIATarget.localTarget().captureScreenWithName(\"hello_instruments\");' > $${TMPDIR}/hello_instruments.js && " + + "/usr/bin/instruments " + + "-t /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.xrplugin/Contents/Resources/Automation.tracetemplate " + + "-w 'iPhone 5 (8.1 Simulator)' " + + "$${TMPDIR}/Payload/PrenotCalculator.app " + + "-e UIASCRIPT $${TMPDIR}/hello_instruments.js " + + "-e UIARESULTSPATH $${TMPDIR} -v && " + + "cp $${TMPDIR}'/Run 1/hello_instruments.png' $(@)", + tags = ["requires-darwin"], +) diff --git a/examples/objc/PrenotCalculator/AppDelegate.h b/examples/objc/PrenotCalculator/AppDelegate.h new file mode 100644 index 0000000000..75b1f1da38 --- /dev/null +++ b/examples/objc/PrenotCalculator/AppDelegate.h @@ -0,0 +1,21 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <UIKit/UIKit.h> + +@interface AppDelegate : UIResponder <UIApplicationDelegate> + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/examples/objc/PrenotCalculator/AppDelegate.m b/examples/objc/PrenotCalculator/AppDelegate.m new file mode 100644 index 0000000000..f6ecc4d6c3 --- /dev/null +++ b/examples/objc/PrenotCalculator/AppDelegate.m @@ -0,0 +1,59 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "AppDelegate.h" + +#import "CalculatorViewController.h" +#import "ValuesViewController.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [self validateBundleLibrary]; + + UITabBarController *bar = [[UITabBarController alloc] init]; + [bar setViewControllers: + @[[[CalculatorViewController alloc] init], [[ValuesViewController alloc] init]]]; + bar.selectedIndex = 0; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = bar; + [self.window makeKeyAndVisible]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application {} + +- (void)applicationDidEnterBackground:(UIApplication *)application {} + +- (void)applicationWillEnterForeground:(UIApplication *)application {} + +- (void)applicationDidBecomeActive:(UIApplication *)application {} + +- (void)applicationWillTerminate:(UIApplication *)application {} + +- (void)validateBundleLibrary { + NSString *bundlePath = [[[NSBundle mainBundle] bundlePath] + stringByAppendingPathComponent:@"PrenotCalculatorResources.bundle"]; + NSBundle *bundle = [NSBundle bundleWithPath:bundlePath]; + NSString *testPath = [bundle pathForResource:@"test" ofType:@"txt"]; + NSString *testContents = [NSString stringWithContentsOfFile:testPath + encoding:NSUTF8StringEncoding + error:NULL]; + NSAssert([testContents hasSuffix:@"It worked!\n"], + @"Unable to find file given mainBundle: %@", + [[NSBundle mainBundle] description]); +} + +@end diff --git a/examples/objc/PrenotCalculator/CalculatedValues.h b/examples/objc/PrenotCalculator/CalculatedValues.h new file mode 100644 index 0000000000..026fadf6ca --- /dev/null +++ b/examples/objc/PrenotCalculator/CalculatedValues.h @@ -0,0 +1,28 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +#import "Equation.h" +#import "Expression.h" + +@interface CalculatedValues : NSObject + ++ (CalculatedValues *)sharedInstance; + +- (NSArray *)values; + +- (void)addEquation:(Equation *)equation; + +@end diff --git a/examples/objc/PrenotCalculator/CalculatedValues.m b/examples/objc/PrenotCalculator/CalculatedValues.m new file mode 100644 index 0000000000..2e401cb1c1 --- /dev/null +++ b/examples/objc/PrenotCalculator/CalculatedValues.m @@ -0,0 +1,48 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "CalculatedValues.h" + +#import "Equation.h" + +@implementation CalculatedValues { + NSMutableArray *_values; +} + ++ (CalculatedValues *)sharedInstance { + static CalculatedValues *values = nil; + if (!values) { + values = [[[self class] alloc] init]; + } + return values; +} + +- (id)init { + self = [super init]; + if (self) { + _values = [NSMutableArray array]; + } + return self; +} + +- (NSArray *)values { + return [_values copy]; +} + +- (void)addEquation:(Equation *)equation { + [_values addObject: + [NSString stringWithFormat:@"%@ = %0.2lf", equation, [equation calculate]]]; +} + +@end diff --git a/examples/objc/PrenotCalculator/CalculatorViewController.h b/examples/objc/PrenotCalculator/CalculatorViewController.h new file mode 100644 index 0000000000..60dbc83bb8 --- /dev/null +++ b/examples/objc/PrenotCalculator/CalculatorViewController.h @@ -0,0 +1,35 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <UIKit/UIKit.h> + +@interface CalculatorViewController : UIViewController + +- (IBAction)enterDigit:(id)sender; + +- (IBAction)finish:(id)sender; + +- (IBAction)operate:(id)sender; + +@property (weak, nonatomic) IBOutlet UIButton *divideButton; +@property (weak, nonatomic) IBOutlet UIButton *multiplyButton; +@property (weak, nonatomic) IBOutlet UIButton *plusButton; +@property (weak, nonatomic) IBOutlet UIButton *minusButton; +@property (strong, nonatomic) IBOutletCollection(UIButton) + NSArray *nonZeroDigitButtons; +@property (weak, nonatomic) IBOutlet UILabel *resultLabel; +@property (weak, nonatomic) IBOutlet UIButton *finishButton; +@property (weak, nonatomic) IBOutlet UIButton *zeroButton; + +@end diff --git a/examples/objc/PrenotCalculator/CalculatorViewController.m b/examples/objc/PrenotCalculator/CalculatorViewController.m new file mode 100644 index 0000000000..5d26fefcc0 --- /dev/null +++ b/examples/objc/PrenotCalculator/CalculatorViewController.m @@ -0,0 +1,127 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "CalculatorViewController.h" + +#import "CalculatedValues.h" +#import "CoreData.h" +#import "Equation.h" +#import "Expression.h" +#import "Literal.h" + +@interface CalculatorViewController () +- (void)updateEnabledViews; +- (void)updateButtonColor:(UIButton *)button; +@end + +@implementation CalculatorViewController { + NSMutableArray *_locationStack; + NSMutableString *_currentNumber; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.title = @"Calculator"; + CoreData *coreData = [[CoreData alloc] init]; + [coreData verify]; + } + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + _locationStack = [NSMutableArray array]; + _currentNumber = [NSMutableString stringWithString:@""]; + [self updateEnabledViews]; +} + +- (IBAction)enterDigit:(id)sender { + UIButton *button = (UIButton *)sender; + [_currentNumber appendString:button.titleLabel.text]; + self.resultLabel.text = _currentNumber; + [self updateEnabledViews]; +} + +- (IBAction)finish:(id)sender { + if (![_locationStack count]) { + _currentNumber = [NSMutableString stringWithString:@""]; + self.resultLabel.text = @"hello"; + } + if (![_locationStack count]) { + _currentNumber = [NSMutableString stringWithString:@""]; + } else if ([_currentNumber length]) { + Equation *last = [_locationStack lastObject]; + [last addExpressionAsChild:[[Literal alloc] initWithDouble: + atof([_currentNumber cStringUsingEncoding:NSUTF8StringEncoding])]]; + _currentNumber = [NSMutableString stringWithString:@""]; + self.resultLabel.text = [NSString stringWithFormat:@"%@", last]; + } else { + Equation *popped = [_locationStack lastObject]; + [_locationStack removeLastObject]; + [[CalculatedValues sharedInstance] addEquation:popped]; + self.resultLabel.text = + [NSString stringWithFormat:@"%lf", [popped calculate]]; + } + [self updateEnabledViews]; +} + +- (IBAction)operate:(id)sender { + Operation operation; + if ([_currentNumber length]) { + // finish the current number first automatically: + [self finish:nil]; + } + if (sender == self.multiplyButton) { + operation = kMultiply; + } else if (sender == self.plusButton) { + operation = kAdd; + } else if (sender == self.divideButton) { + operation = kDivide; + } else if (sender == self.minusButton) { + operation = kSubtract; + } else { + // Shouldn't happen + operation = kAdd; + } + Equation *newEquation = [[Equation alloc] initWithOperation:operation]; + if ([_locationStack count]) { + [[_locationStack lastObject] addExpressionAsChild:newEquation]; + } + [_locationStack addObject:newEquation]; + self.resultLabel.text = [NSString stringWithFormat:@"%@", _locationStack[0]]; + [self updateEnabledViews]; +} + +#pragma mark - Private + + +- (void)updateEnabledViews { + self.finishButton.enabled = [_locationStack count] || [_currentNumber length]; + [self updateButtonColor:self.finishButton]; + self.zeroButton.enabled = self.finishButton.enabled; + [self updateButtonColor:self.zeroButton]; + BOOL enableNonZeroDigits = ![_currentNumber isEqualToString:@"0"]; + for (UIButton *digit in self.nonZeroDigitButtons) { + digit.enabled = enableNonZeroDigits; + [self updateButtonColor:digit]; + } +} + +- (void)updateButtonColor:(UIButton *)button { + button.backgroundColor = button.enabled ? + [UIColor whiteColor] : [UIColor grayColor]; +} + +@end diff --git a/examples/objc/PrenotCalculator/CalculatorViewController.xib b/examples/objc/PrenotCalculator/CalculatorViewController.xib new file mode 100644 index 0000000000..7ed3f42c60 --- /dev/null +++ b/examples/objc/PrenotCalculator/CalculatorViewController.xib @@ -0,0 +1,257 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2015 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="13E28" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CalculatorViewController"> + <connections> + <outlet property="divideButton" destination="STk-6l-Wip" id="gGY-Iy-x7P"/> + <outlet property="finishButton" destination="21D-tW-sLR" id="GnM-vO-sHD"/> + <outlet property="minusButton" destination="7W2-TS-tLI" id="Wuh-b2-g8J"/> + <outlet property="multiplyButton" destination="dwp-YR-bfM" id="MHy-Ot-4Hd"/> + <outlet property="plusButton" destination="4rB-gA-S5X" id="9kZ-af-Os4"/> + <outlet property="resultLabel" destination="N03-1W-Z1G" id="YjW-BO-1Ta"/> + <outlet property="view" destination="1" id="3"/> + <outlet property="zeroButton" destination="YUO-Hc-CsJ" id="dgK-Dt-4YR"/> + <outletCollection property="nonZeroDigitButtons" destination="2ud-fg-6iP" id="SNy-6m-XHb"/> + <outletCollection property="nonZeroDigitButtons" destination="1Od-z8-5N1" id="Iq0-uY-IaD"/> + <outletCollection property="nonZeroDigitButtons" destination="1s9-bG-Fyv" id="CZv-no-Ubi"/> + <outletCollection property="nonZeroDigitButtons" destination="Y9P-jJ-ztr" id="nfC-U0-yxl"/> + <outletCollection property="nonZeroDigitButtons" destination="Iiq-p2-KYo" id="5A3-Y3-95R"/> + <outletCollection property="nonZeroDigitButtons" destination="zR0-hJ-XV8" id="5x0-pC-eis"/> + <outletCollection property="nonZeroDigitButtons" destination="Y4i-o9-uQp" id="qP7-dC-GQ0"/> + <outletCollection property="nonZeroDigitButtons" destination="auh-CA-fzQ" id="NiV-AO-FiS"/> + <outletCollection property="nonZeroDigitButtons" destination="CuZ-P3-3iO" id="snu-lY-DUt"/> + </connections> + </placeholder> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <view contentMode="scaleToFill" id="1"> + <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="hello" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="N03-1W-Z1G"> + <rect key="frame" x="20" y="20" width="280" height="45"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/> + <fontDescription key="fontDescription" name="CourierNewPS-BoldMT" family="Courier New" pointSize="24"/> + <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Y4i-o9-uQp"> + <rect key="frame" x="44" y="73" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="7"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="oJx-RX-3SU"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="auh-CA-fzQ"> + <rect key="frame" x="123" y="73" width="73" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="8"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="pDd-AA-AXS"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CuZ-P3-3iO"> + <rect key="frame" x="205" y="73" width="70" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="9"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="mdP-nK-k9T"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Y9P-jJ-ztr"> + <rect key="frame" x="44" y="149" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="4"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="Eye-1S-G5k"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Iiq-p2-KYo"> + <rect key="frame" x="123" y="149" width="73" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="5"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="NJt-1M-OKG"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zR0-hJ-XV8"> + <rect key="frame" x="205" y="149" width="70" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="6"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="iZc-DU-5Nf"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2ud-fg-6iP"> + <rect key="frame" x="44" y="225" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="1"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="sr8-xD-Dop"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1Od-z8-5N1"> + <rect key="frame" x="125" y="225" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="2"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="r1w-Qx-lmh"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1s9-bG-Fyv"> + <rect key="frame" x="204" y="225" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="3"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="z3W-9d-k3D"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="YUO-Hc-CsJ"> + <rect key="frame" x="125" y="301" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="0"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="enterDigit:" destination="-1" eventType="touchUpInside" id="E2G-nh-OjY"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="21D-tW-sLR"> + <rect key="frame" x="205" y="301" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="↩"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="finish:" destination="-1" eventType="touchUpInside" id="Gr9-nP-eFW"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4rB-gA-S5X"> + <rect key="frame" x="44" y="301" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="+"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="operate:" destination="-1" eventType="touchUpInside" id="pPf-Dl-b44"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dwp-YR-bfM"> + <rect key="frame" x="44" y="377" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="✕"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="operate:" destination="-1" eventType="touchUpInside" id="f6K-EQ-j18"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7W2-TS-tLI"> + <rect key="frame" x="125" y="377" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="-"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="operate:" destination="-1" eventType="touchUpInside" id="MRD-ct-q82"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="STk-6l-Wip"> + <rect key="frame" x="205" y="377" width="71" height="68"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/> + <state key="normal" title="÷"> + <color key="titleColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="operate:" destination="-1" eventType="touchUpInside" id="7cN-RA-mPR"/> + </connections> + </button> + </subviews> + <color key="backgroundColor" red="0.0" green="0.79869981749999996" blue="0.78823562960000004" alpha="1" colorSpace="calibratedRGB"/> + <simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/> + </view> + </objects> +</document>
\ No newline at end of file diff --git a/examples/objc/PrenotCalculator/CoreData.h b/examples/objc/PrenotCalculator/CoreData.h new file mode 100644 index 0000000000..2b55bb1404 --- /dev/null +++ b/examples/objc/PrenotCalculator/CoreData.h @@ -0,0 +1,23 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +// A simple class to confirm CoreData versioning works properly. +@interface CoreData : NSObject + +// Check that the datamodel was loaded properly. +- (void)verify; + +@end diff --git a/examples/objc/PrenotCalculator/CoreData.m b/examples/objc/PrenotCalculator/CoreData.m new file mode 100644 index 0000000000..43a1e89122 --- /dev/null +++ b/examples/objc/PrenotCalculator/CoreData.m @@ -0,0 +1,41 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "CoreData.h" + +@implementation CoreData +- (id)init { + self = [super init]; + if (self) { + + } + return self; +} + +- (void)verify { + NSURL *modelURL = [self modelURL]; + NSAssert(modelURL, + @"Unable to find modelURL given mainBundle: %@", + [[NSBundle mainBundle] description]); +} + +#pragma mark Private Methods. + +- (NSURL *)modelURL { + NSBundle *bundle = [NSBundle bundleForClass:[CoreData class]]; + NSURL *modelURL = [bundle URLForResource:@"DataModel" withExtension:@"momd"]; + return modelURL; +} + +@end diff --git a/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/.xccurrentversion b/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/.xccurrentversion new file mode 100644 index 0000000000..aae30cd305 --- /dev/null +++ b/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/.xccurrentversion @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2015 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>_XCCurrentVersionName</key> + <string>DataModel-1.1.xcdatamodel</string> +</dict> +</plist> diff --git a/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/DataModel-1.0.xcdatamodel/contents b/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/DataModel-1.0.xcdatamodel/contents new file mode 100644 index 0000000000..1cd3e57dae --- /dev/null +++ b/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/DataModel-1.0.xcdatamodel/contents @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + Copyright 2015 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="5063" systemVersion="13C1021" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic"> + <entity name="PCModel" representedClassName="PCModel" syncable="YES"> + <attribute name="one" optional="YES" attributeType="Boolean" syncable="YES"/> + </entity> + <elements> + <element name="PCModel" positionX="0" positionY="0" width="128" height="135"/> + </elements> +</model>
\ No newline at end of file diff --git a/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/DataModel-1.1.xcdatamodel/contents b/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/DataModel-1.1.xcdatamodel/contents new file mode 100644 index 0000000000..80b28dd35a --- /dev/null +++ b/examples/objc/PrenotCalculator/DataModel.xcdatamodeld/DataModel-1.1.xcdatamodel/contents @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + Copyright 2015 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="5063" systemVersion="13C1021" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic"> + <entity name="PCModel" representedClassName="PCModel" syncable="YES"> + <attribute name="one" optional="YES" attributeType="Boolean" syncable="YES"/> + <attribute name="two" optional="YES" attributeType="Boolean" syncable="YES"/> + </entity> + <elements> + <element name="PCModel" positionX="0" positionY="0" width="128" height="135"/> + </elements> +</model>
\ No newline at end of file diff --git a/examples/objc/PrenotCalculator/Equation.h b/examples/objc/PrenotCalculator/Equation.h new file mode 100644 index 0000000000..c04fc705e4 --- /dev/null +++ b/examples/objc/PrenotCalculator/Equation.h @@ -0,0 +1,34 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +#import "Expression.h" + +typedef enum { + kAdd, + kSubtract, + kMultiply, + kDivide +} Operation; + +@interface Equation : Expression + +@property (nonatomic, assign) Operation operation; + +- (id)initWithOperation:(Operation)operation; +- (NSArray *)children; +- (void)addExpressionAsChild:(Expression *)child; + +@end diff --git a/examples/objc/PrenotCalculator/Equation.m b/examples/objc/PrenotCalculator/Equation.m new file mode 100644 index 0000000000..4894e82b93 --- /dev/null +++ b/examples/objc/PrenotCalculator/Equation.m @@ -0,0 +1,108 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "Equation.h" + +@implementation Equation { + NSMutableArray *_children; +} + +@synthesize operation = _operation; + +- (id)init { + [self doesNotRecognizeSelector:_cmd]; + return nil; +} + +- (id)initWithOperation:(Operation)operation { + self = [super init]; + if (self) { + _children = [NSMutableArray array]; + _operation = operation; + } + return self; +} + +- (NSArray *)children { + return [_children copy]; +} + +- (void)addExpressionAsChild:(Expression *)child { + [_children addObject:child]; +} + +- (double)calculate { + if ([_children count] == 1) { + return (_operation == kSubtract) + ? -[_children[0] calculate] : [_children[0] calculate]; + } else if ([_children count] == 0) { + return (_operation == kSubtract || _operation == kAdd) ? 0 : 1; + } + double value = [_children[0] calculate]; + for (Equation *child in [_children subarrayWithRange: + NSMakeRange(1, [_children count] - 1)]) { + double childValue = [child calculate]; + switch (_operation) { + case kAdd: + value += childValue; + break; + case kSubtract: + value -= childValue; + break; + case kMultiply: + value *= childValue; + break; + case kDivide: + value /= childValue; + break; + } + } + return value; +} + +- (NSString *)description { + NSMutableString *result = [[NSMutableString alloc] init]; + [result appendString:@"("]; + switch (_operation) { + case kAdd: + [result appendString:@"+"]; + break; + case kSubtract: + [result appendString:@"-"]; + break; + case kMultiply: + [result appendString:@"*"]; + break; + case kDivide: + [result appendString:@"/"]; + break; + } + for (Equation *child in _children) { + [result appendString:@" "]; + [result appendString:[child description]]; + } + [result appendString:@")"]; + return [result copy]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[self class]]) { + return NO; + } + Equation *other = object; + return other->_operation == _operation && + [other->_children isEqual:_children]; +} + +@end diff --git a/examples/objc/PrenotCalculator/Expression.h b/examples/objc/PrenotCalculator/Expression.h new file mode 100644 index 0000000000..f5b2dcf63e --- /dev/null +++ b/examples/objc/PrenotCalculator/Expression.h @@ -0,0 +1,21 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +@interface Expression : NSObject + +- (double)calculate; + +@end diff --git a/examples/objc/PrenotCalculator/Expression.m b/examples/objc/PrenotCalculator/Expression.m new file mode 100644 index 0000000000..68e954170c --- /dev/null +++ b/examples/objc/PrenotCalculator/Expression.m @@ -0,0 +1,34 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "Expression.h" + +@implementation Expression + +- (double)calculate { + [self doesNotRecognizeSelector:_cmd]; + return NAN; +} + +- (BOOL)isEqual:(id)object { + [self doesNotRecognizeSelector:_cmd]; + return NO; +} + +- (NSString *)description { + [self doesNotRecognizeSelector:_cmd]; + return nil; +} + +@end diff --git a/examples/objc/PrenotCalculator/Literal.h b/examples/objc/PrenotCalculator/Literal.h new file mode 100644 index 0000000000..62ee13c466 --- /dev/null +++ b/examples/objc/PrenotCalculator/Literal.h @@ -0,0 +1,21 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "Expression.h" + +@interface Literal : Expression + +- (id)initWithDouble:(double)value; + +@end diff --git a/examples/objc/PrenotCalculator/Literal.m b/examples/objc/PrenotCalculator/Literal.m new file mode 100644 index 0000000000..c103f46510 --- /dev/null +++ b/examples/objc/PrenotCalculator/Literal.m @@ -0,0 +1,44 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "Literal.h" + +@implementation Literal { + double _value; +} + +- (id)initWithDouble:(double)value { + self = [super init]; + if (self) { + _value = value; + } + return self; +} + +- (double)calculate { + return _value; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%0.2lf", _value]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[self class]]) { + return NO; + } + return _value == ((Literal *)object)->_value; +} + +@end diff --git a/examples/objc/PrenotCalculator/PrenotCalculator-Info.plist b/examples/objc/PrenotCalculator/PrenotCalculator-Info.plist new file mode 100644 index 0000000000..178f34c4c0 --- /dev/null +++ b/examples/objc/PrenotCalculator/PrenotCalculator-Info.plist @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2015 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleDisplayName</key> + <string>PrenotCalculator</string> + <key>CFBundleExecutable</key> + <string>PrenotCalculator</string> + <key>CFBundleIdentifier</key> + <string>Google.PrenotCalculator</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>PrenotCalculator</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> + <key>UISupportedInterfaceOrientations~ipad</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/examples/objc/PrenotCalculator/Resources/test.txt b/examples/objc/PrenotCalculator/Resources/test.txt new file mode 100644 index 0000000000..3dc3aa5164 --- /dev/null +++ b/examples/objc/PrenotCalculator/Resources/test.txt @@ -0,0 +1 @@ +It worked! diff --git a/examples/objc/PrenotCalculator/ValuesViewController.h b/examples/objc/PrenotCalculator/ValuesViewController.h new file mode 100644 index 0000000000..27055b905f --- /dev/null +++ b/examples/objc/PrenotCalculator/ValuesViewController.h @@ -0,0 +1,19 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <UIKit/UIKit.h> + +@interface ValuesViewController : UITableViewController + +@end diff --git a/examples/objc/PrenotCalculator/ValuesViewController.m b/examples/objc/PrenotCalculator/ValuesViewController.m new file mode 100644 index 0000000000..333ea11b1f --- /dev/null +++ b/examples/objc/PrenotCalculator/ValuesViewController.m @@ -0,0 +1,64 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "ValuesViewController.h" + +#import "CalculatedValues.h" + +@interface ValuesViewController () + +@end + +@implementation ValuesViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.title = @"Values"; + } + return self; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView + numberOfRowsInSection:(NSInteger)section { + return [[[CalculatedValues sharedInstance] values] count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *CellIdentifier = @"Cell"; + UITableViewCell *cell = + [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:CellIdentifier]; + } + + cell.textLabel.text = + [CalculatedValues sharedInstance].values[[indexPath indexAtPosition:1]]; + + return cell; +} + +- (void)viewDidAppear:(BOOL)animated { + [self.tableView reloadData]; +} + +@end diff --git a/examples/objc/PrenotCalculator/main.m b/examples/objc/PrenotCalculator/main.m new file mode 100644 index 0000000000..f521bd84bb --- /dev/null +++ b/examples/objc/PrenotCalculator/main.m @@ -0,0 +1,27 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <UIKit/UIKit.h> + +int main(int argc, char * argv[]) { + @autoreleasepool { + NSString *delegateClassName = + #ifndef KIF_TESTS + @"AppDelegate"; + #else + @"AppDelegateForKIF"; + #endif + return UIApplicationMain(argc, argv, nil, delegateClassName); + } +} diff --git a/examples/objc/README.md b/examples/objc/README.md new file mode 100644 index 0000000000..045264fed6 --- /dev/null +++ b/examples/objc/README.md @@ -0,0 +1,17 @@ +Objective C Examples +====== + +The example in this directory show typical use of Objective C libraries, +binaries and imports. Because they build iOS an application they can only be run +on Mac OSX. + +Build the top-level application with +`bazel build examples/objc:PrenotCalculator`, which when finished prints the +path to the generated .ipa. which you can then install to your test device. The +same build will also print the path to an Xcode project directory which you can +open to continue working with the application in Xcode. + +Running `bazel build examples/objc:PrenotCalculatorInstruments` will build and +run the application to obtain a screenshot, the path to which it then prints. + + diff --git a/examples/objc/expression_prebuilt.a b/examples/objc/expression_prebuilt.a Binary files differnew file mode 100644 index 0000000000..8bb74bbb3b --- /dev/null +++ b/examples/objc/expression_prebuilt.a diff --git a/examples/proto/BUILD b/examples/proto/BUILD new file mode 100644 index 0000000000..2228fc4398 --- /dev/null +++ b/examples/proto/BUILD @@ -0,0 +1,8 @@ +package(default_visibility = ["//visibility:public"]) + +load("/tools/build_rules/genproto", "genproto") + +genproto( + name = "test_proto", + src = "test.proto", +) diff --git a/examples/proto/test.proto b/examples/proto/test.proto new file mode 100644 index 0000000000..16a6dc335a --- /dev/null +++ b/examples/proto/test.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package test; + +option java_package = "com.google.test"; + +message KeyVal { + optional string key = 1; + optional string val = 2; +} diff --git a/examples/py/BUILD b/examples/py/BUILD new file mode 100644 index 0000000000..6eecd4a4f3 --- /dev/null +++ b/examples/py/BUILD @@ -0,0 +1,14 @@ +package(default_visibility = ["//visibility:public"]) + +load("/tools/build_rules/py_rules", "py_library", "py_binary") + +py_library( + name = "lib", + srcs = ["lib.py"], +) + +py_binary( + name = "bin", + srcs = ["bin.py"], + deps = [":lib"], +) diff --git a/examples/py/bin.py b/examples/py/bin.py new file mode 100644 index 0000000000..53e917e491 --- /dev/null +++ b/examples/py/bin.py @@ -0,0 +1,3 @@ +from examples.py import lib + +print "Fib(5)=%d" % lib.Fib(5) diff --git a/examples/py/lib.py b/examples/py/lib.py new file mode 100644 index 0000000000..a27d4ce47c --- /dev/null +++ b/examples/py/lib.py @@ -0,0 +1,5 @@ +def Fib(n): + if n == 0 or n == 1: + return 1 + else: + return Fib(n-1) + Fib(n-2) |