laser 0.7.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +14 -0
- data/LICENSE +661 -0
- data/README.md +158 -0
- data/Rakefile +104 -0
- data/VERSION +1 -0
- data/bin/laser +7 -0
- data/design_docs/goals.md +57 -0
- data/design_docs/object_regex.md +426 -0
- data/design_docs/type_annotations.md +80 -0
- data/ext/laser/BasicBlock.cpp +572 -0
- data/ext/laser/BasicBlock.h +118 -0
- data/ext/laser/extconf.rb +3 -0
- data/features/laser.feature +25 -0
- data/features/step_definitions/laser_steps.rb +39 -0
- data/features/support/env.rb +14 -0
- data/features/support/testdata/1_input +1 -0
- data/features/support/testdata/1_output +1 -0
- data/features/support/testdata/2_input +4 -0
- data/features/support/testdata/2_output +4 -0
- data/features/support/testdata/3_input +8 -0
- data/features/support/testdata/3_output +11 -0
- data/features/support/testdata/4_input +5 -0
- data/features/support/testdata/4_output +5 -0
- data/features/support/testdata/5_input +13 -0
- data/laser.gemspec +382 -0
- data/lib/laser.rb +98 -0
- data/lib/laser/analysis/annotations.rb +95 -0
- data/lib/laser/analysis/annotations/annotation_config.yaml +3 -0
- data/lib/laser/analysis/annotations/comment_attachment_annotation.rb +66 -0
- data/lib/laser/analysis/annotations/node_pointers_annotation.rb +36 -0
- data/lib/laser/analysis/annotations/runtime_annotation.rb +55 -0
- data/lib/laser/analysis/argument_expansion.rb +132 -0
- data/lib/laser/analysis/arity.rb +34 -0
- data/lib/laser/analysis/bindings.rb +144 -0
- data/lib/laser/analysis/bootstrap/bootstrap.rb +298 -0
- data/lib/laser/analysis/bootstrap/laser_class.rb +106 -0
- data/lib/laser/analysis/bootstrap/laser_method.rb +255 -0
- data/lib/laser/analysis/bootstrap/laser_module.rb +403 -0
- data/lib/laser/analysis/bootstrap/laser_module_copy.rb +74 -0
- data/lib/laser/analysis/bootstrap/laser_object.rb +69 -0
- data/lib/laser/analysis/bootstrap/laser_proc.rb +150 -0
- data/lib/laser/analysis/bootstrap/laser_singleton_class.rb +44 -0
- data/lib/laser/analysis/comments.rb +35 -0
- data/lib/laser/analysis/control_flow.rb +28 -0
- data/lib/laser/analysis/control_flow/alias_analysis.rb +31 -0
- data/lib/laser/analysis/control_flow/basic_block.rb +105 -0
- data/lib/laser/analysis/control_flow/cfg_builder.rb +2505 -0
- data/lib/laser/analysis/control_flow/cfg_instruction.rb +190 -0
- data/lib/laser/analysis/control_flow/constant_propagation.rb +742 -0
- data/lib/laser/analysis/control_flow/control_flow_graph.rb +370 -0
- data/lib/laser/analysis/control_flow/lifetime_analysis.rb +91 -0
- data/lib/laser/analysis/control_flow/method_call_search.rb +26 -0
- data/lib/laser/analysis/control_flow/raise_properties.rb +25 -0
- data/lib/laser/analysis/control_flow/simulation.rb +385 -0
- data/lib/laser/analysis/control_flow/static_single_assignment.rb +185 -0
- data/lib/laser/analysis/control_flow/unreachability_analysis.rb +57 -0
- data/lib/laser/analysis/control_flow/unused_variables.rb +91 -0
- data/lib/laser/analysis/control_flow/yield_properties.rb +103 -0
- data/lib/laser/analysis/errors.rb +131 -0
- data/lib/laser/analysis/laser_utils.rb +18 -0
- data/lib/laser/analysis/lexical_analysis.rb +172 -0
- data/lib/laser/analysis/method_call.rb +68 -0
- data/lib/laser/analysis/protocol_registry.rb +30 -0
- data/lib/laser/analysis/scope.rb +118 -0
- data/lib/laser/analysis/sexp.rb +159 -0
- data/lib/laser/analysis/sexp_analysis.rb +40 -0
- data/lib/laser/analysis/sexp_extensions/constant_extraction.rb +115 -0
- data/lib/laser/analysis/sexp_extensions/source_location.rb +164 -0
- data/lib/laser/analysis/sexp_extensions/type_inference.rb +47 -0
- data/lib/laser/analysis/signature.rb +76 -0
- data/lib/laser/analysis/special_methods/send.rb +67 -0
- data/lib/laser/analysis/unused_methods.rb +21 -0
- data/lib/laser/analysis/visitor.rb +141 -0
- data/lib/laser/annotation_parser/annotations.treetop +126 -0
- data/lib/laser/annotation_parser/annotations_parser.rb +748 -0
- data/lib/laser/annotation_parser/class_annotations.treetop +82 -0
- data/lib/laser/annotation_parser/class_annotations_parser.rb +654 -0
- data/lib/laser/annotation_parser/overload.treetop +24 -0
- data/lib/laser/annotation_parser/overload_parser.rb +167 -0
- data/lib/laser/annotation_parser/parsers.rb +6 -0
- data/lib/laser/annotation_parser/structural.treetop +37 -0
- data/lib/laser/annotation_parser/structural_parser.rb +406 -0
- data/lib/laser/annotation_parser/useful_parsers.treetop +47 -0
- data/lib/laser/annotation_parser/useful_parsers_parser.rb +674 -0
- data/lib/laser/rake/task.rb +46 -0
- data/lib/laser/runner.rb +189 -0
- data/lib/laser/scanner.rb +169 -0
- data/lib/laser/standard_library/_thread.rb +110 -0
- data/lib/laser/standard_library/abbrev.rb +103 -0
- data/lib/laser/standard_library/array.rb +418 -0
- data/lib/laser/standard_library/base64.rb +91 -0
- data/lib/laser/standard_library/basic_object.rb +55 -0
- data/lib/laser/standard_library/benchmark.rb +556 -0
- data/lib/laser/standard_library/bignum.rb +185 -0
- data/lib/laser/standard_library/cgi.rb +275 -0
- data/lib/laser/standard_library/cgi/cookie.rb +147 -0
- data/lib/laser/standard_library/cgi/core.rb +791 -0
- data/lib/laser/standard_library/cgi/html.rb +1021 -0
- data/lib/laser/standard_library/cgi/session.rb +537 -0
- data/lib/laser/standard_library/cgi/session/pstore.rb +111 -0
- data/lib/laser/standard_library/cgi/util.rb +188 -0
- data/lib/laser/standard_library/class_definitions.rb +333 -0
- data/lib/laser/standard_library/comparable.rb +125 -0
- data/lib/laser/standard_library/complex.rb +162 -0
- data/lib/laser/standard_library/enumerable.rb +178 -0
- data/lib/laser/standard_library/exceptions.rb +135 -0
- data/lib/laser/standard_library/fixnum.rb +188 -0
- data/lib/laser/standard_library/float.rb +180 -0
- data/lib/laser/standard_library/hash.rb +237 -0
- data/lib/laser/standard_library/integer.rb +123 -0
- data/lib/laser/standard_library/laser_magic.rb +7 -0
- data/lib/laser/standard_library/nil_false_true.rb +113 -0
- data/lib/laser/standard_library/numbers.rb +192 -0
- data/lib/laser/standard_library/proc.rb +31 -0
- data/lib/laser/standard_library/set.rb +1348 -0
- data/lib/laser/standard_library/string.rb +666 -0
- data/lib/laser/standard_library/stringio.rb +2 -0
- data/lib/laser/standard_library/symbol.rb +125 -0
- data/lib/laser/standard_library/tsort.rb +242 -0
- data/lib/laser/support/acts_as_struct.rb +66 -0
- data/lib/laser/support/frequency.rb +55 -0
- data/lib/laser/support/inheritable_attributes.rb +145 -0
- data/lib/laser/support/module_extensions.rb +94 -0
- data/lib/laser/support/placeholder_object.rb +13 -0
- data/lib/laser/third_party/rgl/adjacency.rb +221 -0
- data/lib/laser/third_party/rgl/base.rb +228 -0
- data/lib/laser/third_party/rgl/bidirectional.rb +39 -0
- data/lib/laser/third_party/rgl/condensation.rb +47 -0
- data/lib/laser/third_party/rgl/connected_components.rb +138 -0
- data/lib/laser/third_party/rgl/control_flow.rb +170 -0
- data/lib/laser/third_party/rgl/depth_first_spanning_tree.rb +37 -0
- data/lib/laser/third_party/rgl/dominators.rb +124 -0
- data/lib/laser/third_party/rgl/dot.rb +93 -0
- data/lib/laser/third_party/rgl/graphxml.rb +51 -0
- data/lib/laser/third_party/rgl/implicit.rb +174 -0
- data/lib/laser/third_party/rgl/mutable.rb +117 -0
- data/lib/laser/third_party/rgl/rdot.rb +445 -0
- data/lib/laser/third_party/rgl/topsort.rb +72 -0
- data/lib/laser/third_party/rgl/transitivity.rb +180 -0
- data/lib/laser/third_party/rgl/traversal.rb +348 -0
- data/lib/laser/types/types.rb +433 -0
- data/lib/laser/version.rb +14 -0
- data/lib/laser/warning.rb +149 -0
- data/lib/laser/warning_sets/default.yml +13 -0
- data/lib/laser/warnings/assignment_in_condition.rb +20 -0
- data/lib/laser/warnings/comment_spacing.rb +31 -0
- data/lib/laser/warnings/extra_blank_lines.rb +30 -0
- data/lib/laser/warnings/extra_whitespace.rb +16 -0
- data/lib/laser/warnings/hash_symbol_18_warning.rb +63 -0
- data/lib/laser/warnings/hash_symbol_19_warning.rb +29 -0
- data/lib/laser/warnings/line_length.rb +115 -0
- data/lib/laser/warnings/misaligned_unindentation.rb +17 -0
- data/lib/laser/warnings/operator_spacing.rb +68 -0
- data/lib/laser/warnings/parens_on_declaration.rb +30 -0
- data/lib/laser/warnings/rescue_exception.rb +42 -0
- data/lib/laser/warnings/semicolon.rb +25 -0
- data/lib/laser/warnings/sexp_errors.rb +24 -0
- data/lib/laser/warnings/uncalled_method_warning.rb +7 -0
- data/lib/laser/warnings/useless_double_quotes.rb +38 -0
- data/spec/analysis_specs/annotations_spec.rb +47 -0
- data/spec/analysis_specs/annotations_specs/comment_attachment_spec.rb +68 -0
- data/spec/analysis_specs/annotations_specs/node_pointers_annotation_spec.rb +90 -0
- data/spec/analysis_specs/annotations_specs/runtime_annotation_spec.rb +135 -0
- data/spec/analysis_specs/annotations_specs/spec_helper.rb +33 -0
- data/spec/analysis_specs/argument_expansion_spec.rb +113 -0
- data/spec/analysis_specs/bindings_spec.rb +36 -0
- data/spec/analysis_specs/comment_spec.rb +93 -0
- data/spec/analysis_specs/control_flow_specs/cfg_instruction_spec.rb +111 -0
- data/spec/analysis_specs/control_flow_specs/constant_propagation_spec.rb +560 -0
- data/spec/analysis_specs/control_flow_specs/control_flow_graph_spec.rb +5 -0
- data/spec/analysis_specs/control_flow_specs/raise_properties_spec.rb +310 -0
- data/spec/analysis_specs/control_flow_specs/raise_type_inference_spec.rb +301 -0
- data/spec/analysis_specs/control_flow_specs/return_type_inference_spec.rb +431 -0
- data/spec/analysis_specs/control_flow_specs/simulation_spec.rb +158 -0
- data/spec/analysis_specs/control_flow_specs/spec_helper.rb +110 -0
- data/spec/analysis_specs/control_flow_specs/tuple_misuse_inference_spec.rb +125 -0
- data/spec/analysis_specs/control_flow_specs/unreachability_analysis_spec.rb +76 -0
- data/spec/analysis_specs/control_flow_specs/unused_variable_spec.rb +99 -0
- data/spec/analysis_specs/control_flow_specs/yield_properties_spec.rb +372 -0
- data/spec/analysis_specs/error_spec.rb +30 -0
- data/spec/analysis_specs/laser_class_spec.rb +322 -0
- data/spec/analysis_specs/lexical_analysis_spec.rb +184 -0
- data/spec/analysis_specs/protocol_registry_spec.rb +63 -0
- data/spec/analysis_specs/scope_annotation_spec.rb +1013 -0
- data/spec/analysis_specs/scope_spec.rb +126 -0
- data/spec/analysis_specs/sexp_analysis_spec.rb +30 -0
- data/spec/analysis_specs/sexp_extension_specs/constant_extraction_spec.rb +309 -0
- data/spec/analysis_specs/sexp_extension_specs/source_location_spec.rb +231 -0
- data/spec/analysis_specs/sexp_extension_specs/spec_helper.rb +1 -0
- data/spec/analysis_specs/sexp_extension_specs/type_inference_spec.rb +252 -0
- data/spec/analysis_specs/sexp_spec.rb +167 -0
- data/spec/analysis_specs/spec_helper.rb +27 -0
- data/spec/analysis_specs/unused_methods_spec.rb +65 -0
- data/spec/analysis_specs/visitor_spec.rb +64 -0
- data/spec/annotation_parser_specs/annotations_parser_spec.rb +89 -0
- data/spec/annotation_parser_specs/class_annotation_parser_spec.rb +120 -0
- data/spec/annotation_parser_specs/overload_parser_spec.rb +39 -0
- data/spec/annotation_parser_specs/parsers_spec.rb +14 -0
- data/spec/annotation_parser_specs/spec_helper.rb +1 -0
- data/spec/annotation_parser_specs/structural_parser_spec.rb +67 -0
- data/spec/laser_spec.rb +14 -0
- data/spec/rake_specs/spec_helper.rb +1 -0
- data/spec/rake_specs/task_spec.rb +67 -0
- data/spec/runner_spec.rb +207 -0
- data/spec/scanner_spec.rb +75 -0
- data/spec/spec_helper.rb +121 -0
- data/spec/standard_library/exceptions_spec.rb +19 -0
- data/spec/standard_library/globals_spec.rb +14 -0
- data/spec/standard_library/set_spec.rb +31 -0
- data/spec/standard_library/spec_helper.rb +1 -0
- data/spec/standard_library/standard_library_spec.rb +302 -0
- data/spec/support_specs/acts_as_struct_spec.rb +94 -0
- data/spec/support_specs/frequency_spec.rb +23 -0
- data/spec/support_specs/module_extensions_spec.rb +117 -0
- data/spec/support_specs/spec_helper.rb +1 -0
- data/spec/type_specs/spec_helper.rb +1 -0
- data/spec/type_specs/types_spec.rb +133 -0
- data/spec/warning_spec.rb +95 -0
- data/spec/warning_specs/assignment_in_condition_spec.rb +68 -0
- data/spec/warning_specs/comment_spacing_spec.rb +65 -0
- data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
- data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
- data/spec/warning_specs/hash_symbol_18_warning_spec.rb +89 -0
- data/spec/warning_specs/hash_symbol_19_warning_spec.rb +63 -0
- data/spec/warning_specs/line_length_spec.rb +173 -0
- data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
- data/spec/warning_specs/operator_spacing_spec.rb +104 -0
- data/spec/warning_specs/parens_on_declaration_spec.rb +57 -0
- data/spec/warning_specs/rescue_exception_spec.rb +105 -0
- data/spec/warning_specs/semicolon_spec.rb +58 -0
- data/spec/warning_specs/spec_helper.rb +1 -0
- data/spec/warning_specs/useless_double_quotes_spec.rb +74 -0
- data/status_reports/2010/12/2010-12-14.md +163 -0
- data/status_reports/2010/12/2010-12-23.md +298 -0
- data/status_reports/2010/12/2010-12-24.md +6 -0
- data/test/third_party_tests/rgl_tests/TestComponents.rb +65 -0
- data/test/third_party_tests/rgl_tests/TestCycles.rb +61 -0
- data/test/third_party_tests/rgl_tests/TestDirectedGraph.rb +125 -0
- data/test/third_party_tests/rgl_tests/TestDot.rb +18 -0
- data/test/third_party_tests/rgl_tests/TestEdge.rb +34 -0
- data/test/third_party_tests/rgl_tests/TestGraph.rb +71 -0
- data/test/third_party_tests/rgl_tests/TestGraphXML.rb +57 -0
- data/test/third_party_tests/rgl_tests/TestImplicit.rb +52 -0
- data/test/third_party_tests/rgl_tests/TestRdot.rb +863 -0
- data/test/third_party_tests/rgl_tests/TestTransitivity.rb +129 -0
- data/test/third_party_tests/rgl_tests/TestTraversal.rb +220 -0
- data/test/third_party_tests/rgl_tests/TestUnDirectedGraph.rb +102 -0
- data/test/third_party_tests/rgl_tests/examples/north/Graph.log +128 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.0.graphml +28 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.1.graphml +28 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.11.graphml +31 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.12.graphml +27 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.13.graphml +27 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.14.graphml +27 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.15.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.16.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.17.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.19.graphml +37 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.2.graphml +28 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.20.graphml +38 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.22.graphml +43 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.24.graphml +30 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.25.graphml +45 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.27.graphml +38 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.28.graphml +30 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.29.graphml +38 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.3.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.30.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.31.graphml +42 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.34.graphml +42 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.37.graphml +28 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.38.graphml +38 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.39.graphml +36 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.4.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.40.graphml +37 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.41.graphml +37 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.42.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.45.graphml +28 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.46.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.5.graphml +31 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.50.graphml +30 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.56.graphml +29 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.57.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.58.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.6.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.60.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.61.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.62.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.68.graphml +30 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.69.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.7.graphml +29 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.70.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.71.graphml +27 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.72.graphml +28 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.74.graphml +29 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.75.graphml +29 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.78.graphml +27 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.79.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.8.graphml +29 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.80.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.82.graphml +35 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.83.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.85.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.86.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.88.graphml +37 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.89.graphml +29 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.9.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.90.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.91.graphml +31 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.92.graphml +26 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.93.graphml +32 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.10.94.graphml +34 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.12.8.graphml +40 -0
- data/test/third_party_tests/rgl_tests/examples/north/g.14.9.graphml +36 -0
- data/test/third_party_tests/rgl_tests/test_helper.rb +7 -0
- data/test/third_party_tests/test_inheritable_attributes.rb +187 -0
- metadata +470 -0
@@ -0,0 +1,145 @@
|
|
1
|
+
module Laser
|
2
|
+
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
|
3
|
+
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
|
4
|
+
# to, for example, an array without those additions being shared with either their parent, siblings, or
|
5
|
+
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
|
6
|
+
module InheritedAttributes # :nodoc:
|
7
|
+
def self.extended(base)
|
8
|
+
return if const_defined?(:Rails)
|
9
|
+
base.__send__(:extend, ClassMethods)
|
10
|
+
class << base
|
11
|
+
alias inherited_without_inheritable_attributes inherited
|
12
|
+
alias inherited inherited_with_inheritable_attributes
|
13
|
+
end
|
14
|
+
end
|
15
|
+
module ClassMethods
|
16
|
+
def class_inheritable_reader(*syms)
|
17
|
+
syms.each do |sym|
|
18
|
+
next if sym.is_a?(Hash)
|
19
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
20
|
+
def self.#{sym} # def self.after_add
|
21
|
+
read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:after_add)
|
22
|
+
end # end
|
23
|
+
#
|
24
|
+
def #{sym} # def after_add
|
25
|
+
self.class.#{sym} # self.class.after_add
|
26
|
+
end # end
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def class_inheritable_writer(*syms)
|
32
|
+
syms.each do |sym|
|
33
|
+
next if sym.is_a?(Hash)
|
34
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
35
|
+
def self.#{sym}=(obj) # def self.color=(obj)
|
36
|
+
write_inheritable_attribute(:#{sym}, obj) # write_inheritable_attribute(:color, obj)
|
37
|
+
end # end
|
38
|
+
#
|
39
|
+
def #{sym}=(obj) # def color=(obj)
|
40
|
+
self.class.#{sym} = obj # self.class.color = obj
|
41
|
+
end # end
|
42
|
+
EOS
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def class_inheritable_array_writer(*syms)
|
47
|
+
syms.each do |sym|
|
48
|
+
next if sym.is_a?(Hash)
|
49
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
50
|
+
def self.#{sym}=(obj) # def self.levels=(obj)
|
51
|
+
write_inheritable_array(:#{sym}, obj) # write_inheritable_array(:levels, obj)
|
52
|
+
end # end
|
53
|
+
#
|
54
|
+
def #{sym}=(obj) # def levels=(obj)
|
55
|
+
self.class.#{sym} = obj # self.class.levels = obj
|
56
|
+
end # end
|
57
|
+
EOS
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def class_inheritable_hash_writer(*syms)
|
62
|
+
syms.each do |sym|
|
63
|
+
next if sym.is_a?(Hash)
|
64
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
65
|
+
def self.#{sym}=(obj) # def self.nicknames=(obj)
|
66
|
+
write_inheritable_hash(:#{sym}, obj) # write_inheritable_hash(:nicknames, obj)
|
67
|
+
end # end
|
68
|
+
#
|
69
|
+
def #{sym}=(obj) # def nicknames=(obj)
|
70
|
+
self.class.#{sym} = obj # self.class.nicknames = obj
|
71
|
+
end # end
|
72
|
+
EOS
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def class_inheritable_accessor(*syms)
|
77
|
+
class_inheritable_reader(*syms)
|
78
|
+
class_inheritable_writer(*syms)
|
79
|
+
end
|
80
|
+
|
81
|
+
def class_inheritable_array(*syms)
|
82
|
+
class_inheritable_reader(*syms)
|
83
|
+
class_inheritable_array_writer(*syms)
|
84
|
+
end
|
85
|
+
|
86
|
+
def class_inheritable_hash(*syms)
|
87
|
+
class_inheritable_reader(*syms)
|
88
|
+
class_inheritable_hash_writer(*syms)
|
89
|
+
end
|
90
|
+
|
91
|
+
def inheritable_attributes
|
92
|
+
@inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
|
93
|
+
end
|
94
|
+
|
95
|
+
def write_inheritable_attribute(key, value)
|
96
|
+
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
|
97
|
+
@inheritable_attributes = {}
|
98
|
+
end
|
99
|
+
inheritable_attributes[key] = value
|
100
|
+
end
|
101
|
+
|
102
|
+
def write_inheritable_array(key, elements)
|
103
|
+
write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
|
104
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
|
105
|
+
end
|
106
|
+
|
107
|
+
def write_inheritable_hash(key, hash)
|
108
|
+
write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
|
109
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
|
110
|
+
end
|
111
|
+
|
112
|
+
def read_inheritable_attribute(key)
|
113
|
+
inheritable_attributes[key]
|
114
|
+
end
|
115
|
+
|
116
|
+
def reset_inheritable_attributes
|
117
|
+
@inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
# Prevent this constant from being created multiple times
|
122
|
+
EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
|
123
|
+
|
124
|
+
def duplicable?(x)
|
125
|
+
![NilClass, FalseClass, TrueClass, Module, ::Symbol, Numeric].any? do |klass|
|
126
|
+
x.is_a?(klass)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def inherited_with_inheritable_attributes(child)
|
131
|
+
inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
|
132
|
+
|
133
|
+
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
|
134
|
+
new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
|
135
|
+
else
|
136
|
+
new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
|
137
|
+
memo.update(key => duplicable?(value) ? value.dup : value)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Laser
|
2
|
+
# These are extensions to Laser modules. This module should be
|
3
|
+
# extended by any Laser modules seeking to take advantage of them.
|
4
|
+
# This prevents conflicts with other libraries defining extensions
|
5
|
+
# of the same name.
|
6
|
+
module ModuleExtensions
|
7
|
+
# Creates a new method that returns the boolean negation of the
|
8
|
+
# specified method.
|
9
|
+
def opposite_method(new_name, old_name)
|
10
|
+
define_method new_name do |*args, &blk|
|
11
|
+
!send(old_name, *args, &blk)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Creates an attr_accessor that defaults to a certain value.
|
16
|
+
def attr_accessor_with_default(name, val)
|
17
|
+
ivar_sym = "@#{name}"
|
18
|
+
define_method name do
|
19
|
+
unless instance_variable_defined?(ivar_sym)
|
20
|
+
instance_variable_set(ivar_sym, val)
|
21
|
+
end
|
22
|
+
instance_variable_get ivar_sym
|
23
|
+
end
|
24
|
+
attr_writer name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a reader for the given instance variables on the class object.
|
28
|
+
def cattr_reader(*attrs)
|
29
|
+
attrs.each do |attr|
|
30
|
+
instance_eval("def #{attr}; @#{attr}; end")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creates a writer for the given instance variables on the class object.
|
35
|
+
def cattr_writer(*attrs)
|
36
|
+
attrs.each do |attr|
|
37
|
+
instance_eval("def #{attr}=(val); @#{attr} = val; end")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates readers and writers for the given instance variables.
|
42
|
+
def cattr_accessor(*attrs)
|
43
|
+
cattr_reader(*attrs)
|
44
|
+
cattr_writer(*attrs)
|
45
|
+
end
|
46
|
+
|
47
|
+
def cattr_accessor_with_default(attr, default)
|
48
|
+
varname = "@#{attr}".to_sym
|
49
|
+
singleton_class.instance_eval do
|
50
|
+
define_method attr do
|
51
|
+
if instance_variable_defined?(varname)
|
52
|
+
instance_variable_get(varname)
|
53
|
+
else
|
54
|
+
default = default.dup unless Fixnum === default || default.singleton_class == default.class
|
55
|
+
instance_variable_set(varname, default)
|
56
|
+
instance_variable_get(varname)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
cattr_writer(attr)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Creates a DSL-friendly set-and-getter method. The method, when called with
|
64
|
+
# no arguments, acts as a getter. When called with arguments, it acts as a
|
65
|
+
# setter. Uses class instance variables - this is not for generating
|
66
|
+
# instance methods.
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
# class A
|
70
|
+
# cattr_get_and_setter :type
|
71
|
+
# end
|
72
|
+
# class B < A
|
73
|
+
# type :silly
|
74
|
+
# end
|
75
|
+
# p B.type # => :silly
|
76
|
+
def cattr_get_and_setter(*attrs)
|
77
|
+
attrs.each do |attr|
|
78
|
+
cattr_accessor attr
|
79
|
+
singleton_class.instance_eval do
|
80
|
+
alias_method "#{attr}_old_get".to_sym, attr
|
81
|
+
define_method attr do |*args, &blk|
|
82
|
+
if args.size > 0
|
83
|
+
send("#{attr}=", *args)
|
84
|
+
elsif blk != nil
|
85
|
+
send("#{attr}=", blk)
|
86
|
+
else
|
87
|
+
send("#{attr}_old_get")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Laser
|
2
|
+
# Class that's just a name. Substitute for symbols, which can overlap
|
3
|
+
# with user-code values.
|
4
|
+
class PlaceholderObject
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
def inspect
|
9
|
+
@name
|
10
|
+
end
|
11
|
+
alias_method :to_s, :inspect
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# adjacency.rb
|
2
|
+
#
|
3
|
+
# $Id: adjacency.rb,v 1.12 2008/08/23 05:37:05 javanthropus Exp $
|
4
|
+
#
|
5
|
+
# The DirectedAdjacencyGraph class implements a generalized adjacency list
|
6
|
+
# graph structure. An AdjacencyGraph is basically a two-dimensional structure
|
7
|
+
# (ie, a list of lists). Each element of the first dimension represents a
|
8
|
+
# vertex. Each of the vertices contains a one-dimensional structure that is
|
9
|
+
# the list of all adjacent vertices.
|
10
|
+
#
|
11
|
+
# The class for representing the adjacency list of a vertex is, by default, a
|
12
|
+
# Set. This can be configured by the client, however, when an AdjacencyGraph
|
13
|
+
# is created.
|
14
|
+
|
15
|
+
require 'laser/third_party/rgl/mutable'
|
16
|
+
require 'set'
|
17
|
+
|
18
|
+
module RGL
|
19
|
+
class DirectedAdjacencyGraph
|
20
|
+
|
21
|
+
include MutableGraph
|
22
|
+
|
23
|
+
# Shortcut for creating a DirectedAdjacencyGraph:
|
24
|
+
#
|
25
|
+
# RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s =>
|
26
|
+
# "(1-2)(2-3)(2-4)(4-5)"
|
27
|
+
|
28
|
+
def self.[] (*a)
|
29
|
+
result = new
|
30
|
+
0.step(a.size-1, 2) { |i| result.add_edge(a[i], a[i+1]) }
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a new empty DirectedAdjacencyGraph which has as its edgelist
|
35
|
+
# class the given class. The default edgelist class is Set, to ensure
|
36
|
+
# set semantics for edges and vertices.
|
37
|
+
#
|
38
|
+
# If other graphs are passed as parameters their vertices and edges are
|
39
|
+
# added to the new graph.
|
40
|
+
def initialize (edgelist_class = Set, *other_graphs)
|
41
|
+
@edgelist_class = edgelist_class
|
42
|
+
@vertex_dict = Hash.new
|
43
|
+
@predecessor_dict = Hash.new
|
44
|
+
|
45
|
+
add_graphs(*other_graphs)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Copy internal vertice_dict
|
49
|
+
def initialize_copy(orig)
|
50
|
+
@vertex_dict = orig.instance_eval{@vertex_dict}.dup
|
51
|
+
@vertex_dict.keys.each do |v|
|
52
|
+
@vertex_dict[v] = @vertex_dict[v].dup
|
53
|
+
end
|
54
|
+
@predecessor_dict = orig.instance_eval{@predecessor_dict}.dup
|
55
|
+
@predecessor_dict.keys.each do |v|
|
56
|
+
@predecessor_dict[v] = @predecessor_dict[v].dup
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Iterator for the keys of the vertice list hash.
|
61
|
+
|
62
|
+
def each_vertex (&b)
|
63
|
+
@vertex_dict.each_key(&b)
|
64
|
+
end
|
65
|
+
|
66
|
+
def each_adjacent (v, &b) # :nodoc:
|
67
|
+
adjacency_list = (@vertex_dict[v] or
|
68
|
+
raise NoVertexError, "No vertex #{v}.")
|
69
|
+
adjacency_list.each(&b)
|
70
|
+
end
|
71
|
+
|
72
|
+
def each_predecessor(v, &b)
|
73
|
+
predecessor_dict = (@predecessor_dict[v] or
|
74
|
+
raise NoVertexError, "No vertex #{v}.")
|
75
|
+
predecessor_dict.each(&b)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns true.
|
79
|
+
|
80
|
+
def directed?
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
# Complexity is O(1), because the vertices are kept in a Hash containing
|
85
|
+
# as values the lists of adjacent vertices of _v_.
|
86
|
+
|
87
|
+
def has_vertex? (v)
|
88
|
+
@vertex_dict.has_key?(v)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Complexity is O(1), if a Set is used as adjacency list. Otherwise,
|
92
|
+
# complexity is O(out_degree(v)).
|
93
|
+
#
|
94
|
+
# ---
|
95
|
+
# MutableGraph interface.
|
96
|
+
|
97
|
+
def has_edge? (u, v)
|
98
|
+
has_vertex?(u) and @vertex_dict[u].include?(v)
|
99
|
+
end
|
100
|
+
|
101
|
+
# See MutableGraph#add_vertex.
|
102
|
+
#
|
103
|
+
# If the vertex is already in the graph (using eql?), the method does
|
104
|
+
# nothing.
|
105
|
+
|
106
|
+
def add_vertex (v)
|
107
|
+
@vertex_dict[v] ||= @edgelist_class.new
|
108
|
+
@predecessor_dict[v] ||= @edgelist_class.new
|
109
|
+
end
|
110
|
+
|
111
|
+
# See MutableGraph#add_edge.
|
112
|
+
|
113
|
+
def add_edge (u, v)
|
114
|
+
add_vertex(u) # ensure key
|
115
|
+
add_vertex(v) # ensure key
|
116
|
+
basic_add_edge(u, v)
|
117
|
+
end
|
118
|
+
|
119
|
+
# See MutableGraph#remove_vertex.
|
120
|
+
|
121
|
+
def remove_vertex (v)
|
122
|
+
@vertex_dict.delete(v)
|
123
|
+
@predecessor_dict.delete(v)
|
124
|
+
# remove v from all adjacency lists
|
125
|
+
|
126
|
+
@vertex_dict.each_value { |adjList| adjList.delete(v) }
|
127
|
+
@predecessor_dict.each_value { |predlist| predlist.delete(v) }
|
128
|
+
end
|
129
|
+
|
130
|
+
# See MutableGraph::remove_edge.
|
131
|
+
|
132
|
+
def remove_edge (u, v)
|
133
|
+
@vertex_dict[u].delete(v) unless @vertex_dict[u].nil?
|
134
|
+
@predecessor_dict[v].delete(u) unless @predecessor_dict[v].nil?
|
135
|
+
end
|
136
|
+
|
137
|
+
# Converts the adjacency list of each vertex to be of type _klass_. The
|
138
|
+
# class is expected to have a new contructor which accepts an enumerable as
|
139
|
+
# parameter.
|
140
|
+
def edgelist_class=(klass)
|
141
|
+
@vertex_dict.keys.each do |v|
|
142
|
+
@vertex_dict[v] = klass.new @vertex_dict[v].to_a
|
143
|
+
end
|
144
|
+
@predecessor_dict.keys.each do |v|
|
145
|
+
@predecessor_dict[v] = klass.new @predecessor_dict[v].to_a
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
protected
|
150
|
+
|
151
|
+
def basic_add_edge (u, v)
|
152
|
+
@vertex_dict[u].add(v)
|
153
|
+
@predecessor_dict[v].add(u)
|
154
|
+
end
|
155
|
+
|
156
|
+
end # class DirectedAdjacencyGraph
|
157
|
+
|
158
|
+
# AdjacencyGraph is an undirected Graph. The methods add_edge and
|
159
|
+
# remove_edge are reimplemented: If an edge (u,v) is added or removed,
|
160
|
+
# then the reverse edge (v,u) is also added or removed.
|
161
|
+
|
162
|
+
class AdjacencyGraph < DirectedAdjacencyGraph
|
163
|
+
|
164
|
+
def directed? # Always returns false.
|
165
|
+
false
|
166
|
+
end
|
167
|
+
|
168
|
+
# Also removes (v,u)
|
169
|
+
|
170
|
+
def remove_edge (u, v)
|
171
|
+
super
|
172
|
+
@vertex_dict[v].delete(u) unless @vertex_dict[v].nil?
|
173
|
+
end
|
174
|
+
|
175
|
+
protected
|
176
|
+
|
177
|
+
def basic_add_edge (u,v)
|
178
|
+
super
|
179
|
+
@vertex_dict[v].add(u) # Insert backwards edge
|
180
|
+
end
|
181
|
+
|
182
|
+
end # class AdjacencyGraph
|
183
|
+
|
184
|
+
module Graph
|
185
|
+
|
186
|
+
# Convert a general graph to an AdjacencyGraph. If the graph is directed,
|
187
|
+
# returns a DirectedAdjacencyGraph; otherwise, returns an AdjacencyGraph.
|
188
|
+
|
189
|
+
def to_adjacency
|
190
|
+
result = (directed? ? DirectedAdjacencyGraph : AdjacencyGraph).new
|
191
|
+
each_vertex { |v| result.add_vertex(v) }
|
192
|
+
each_edge { |u,v| result.add_edge(u, v) }
|
193
|
+
result
|
194
|
+
end
|
195
|
+
|
196
|
+
# Return a new DirectedAdjacencyGraph which has the same set of vertices.
|
197
|
+
# If (u,v) is an edge of the graph, then (v,u) is an edge of the result.
|
198
|
+
#
|
199
|
+
# If the graph is undirected, the result is self.
|
200
|
+
|
201
|
+
def reverse
|
202
|
+
return self unless directed?
|
203
|
+
result = DirectedAdjacencyGraph.new
|
204
|
+
each_vertex { |v| result.add_vertex v }
|
205
|
+
each_edge { |u,v| result.add_edge(v, u) }
|
206
|
+
result
|
207
|
+
end
|
208
|
+
|
209
|
+
# Return a new AdjacencyGraph which has the same set of vertices. If (u,v)
|
210
|
+
# is an edge of the graph, then (u,v) and (v,u) (which are the same edges)
|
211
|
+
# are edges of the result.
|
212
|
+
#
|
213
|
+
# If the graph is undirected, the result is self.
|
214
|
+
|
215
|
+
def to_undirected
|
216
|
+
return self unless directed?
|
217
|
+
AdjacencyGraph.new(Set, self)
|
218
|
+
end
|
219
|
+
|
220
|
+
end # module Graph
|
221
|
+
end # module RGL
|