aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/core/selector/abstract-selector.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/core/selector/abstract-selector.js')
-rw-r--r--node_modules/montage/core/selector/abstract-selector.js189
1 files changed, 189 insertions, 0 deletions
diff --git a/node_modules/montage/core/selector/abstract-selector.js b/node_modules/montage/core/selector/abstract-selector.js
new file mode 100644
index 00000000..69bbb810
--- /dev/null
+++ b/node_modules/montage/core/selector/abstract-selector.js
@@ -0,0 +1,189 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6
7var Parser = require("./parser").Parser;
8
9exports.makeSelector = makeSelector;
10function makeSelector(language) {
11
12 var tokens = language.tokens;
13 var tokenNames = language.tokenNames;
14 var semantics = language.semantics;
15
16 var Selector = function () {
17 return makeTokenEmitter(
18 Selector.newWithLanguage(language),
19 tokenEmitterProperties
20 ).apply(null, arguments);
21 };
22
23 Object.defineProperties(Selector, selectorProperties);
24
25 Selector.language = language;
26
27 var tokenEmitterProperties = language.selectorExtras || {};
28 var extraTokenEmitterNames = Object.keys(tokenEmitterProperties);
29
30 // Proxied properties of the underlying selector
31 ['tokens', 'evaluate', 'compile', 'parser', 'syntax']
32 .forEach(function (name) {
33 tokenEmitterProperties[name] = {get: function () {
34 return this.selector[name];
35 }};
36 });
37
38 tokenNames.forEach(function (name) {
39 tokenEmitterProperties[name] = {
40 get: function () {
41 this.emit(tokens[name]);
42 return this;
43 }
44 };
45 });
46
47 // TODO compute array from extras, move emit from extras
48 tokenNames
49 .concat(extraTokenEmitterNames)
50 .forEach(function (name) {
51 Object.defineProperty(Selector, name, {
52 get: function () {
53 var selector = this.newWithLanguage(language);
54 var proxy = makeTokenEmitter(
55 selector,
56 tokenEmitterProperties
57 )[name];
58 Object.defineProperties(proxy, tokenEmitterProperties);
59 proxy.selector = selector;
60 return proxy;
61 }
62 });
63 });
64
65 Selector.__start = function (token) {
66 return makeTokenEmitter(
67 Selector.newWithLanguage(language),
68 tokenEmitterProperties
69 );
70 };
71
72 return Selector;
73}
74
75exports._makeTokenEmitter = makeTokenEmitter;
76function makeTokenEmitter(selector, tokenEmitterProperties) {
77 var tokenEmitter = function () {
78 var lastIndex = arguments.length - 1;
79 Array.prototype.forEach.call(arguments, function (argument, index) {
80 if (argument != null && argument.tokens) {
81 selector.emit(selector.language.tokens.begin);
82 argument.tokens.forEach(function (token) {
83 selector.emit(token);
84 });
85 selector.emit(selector.language.tokens.end);
86 } else {
87 selector.emit({type: 'literal', value: argument});
88 }
89 if (index !== lastIndex) {
90 selector.emit(selector.language.tokens.comma);
91 }
92 });
93 return tokenEmitter;
94 };
95 Object.defineProperties(tokenEmitter, tokenEmitterProperties);
96 tokenEmitter.emit = function (token) {
97 tokenEmitter.selector.emit(token);
98 return tokenEmitter;
99 };
100 tokenEmitter.selector = selector;
101 tokenEmitter.language = selector.language;
102 return tokenEmitter;
103}
104
105var selectorProperties = {
106
107 newWithLanguage: {
108 value: function (language) {
109 var self = Object.create(this);
110 self.language = language;
111 self.parser = Parser.newWithLanguage(language, function (syntax) {
112 self._syntax = syntax;
113 });
114 return self;
115 }
116 },
117
118 fromSyntax: {
119 value: function (syntax) {
120 var self = Object.create(this);
121 self._syntax = syntax;
122 return self;
123 }
124 },
125
126 tokens: {
127 get: function () {
128 if (!this.parser) {
129 return [];
130 } else {
131 return this.parser.tokens;
132 }
133 }
134 },
135
136 emit: {
137 value: function (token) {
138 if (!this.parser) {
139 return this.__start().emit(token);
140 } else {
141 this.parser.emit(token);
142 return this;
143 }
144 }
145 },
146
147 syntax: {
148 get: function () {
149 if (!this.parser) {
150 return this.language.tokens.value;
151 } else {
152 this.emit(this.language.tokens.eof);
153 return this._syntax;
154 }
155 }
156 },
157
158 compile: {
159 value: function (parameters) {
160 if (!this.parser) {
161 return function (value) {
162 return value;
163 };
164 } else {
165 return this.language.semantics.compile(
166 this.syntax,
167 parameters
168 );
169 }
170 }
171 },
172
173 evaluate: {
174 value: function (value, parameters, visitor) {
175 if (!this.parser) {
176 return value;
177 } else {
178 return this.language.semantics.evaluate(
179 this.syntax,
180 value,
181 parameters,
182 visitor
183 );
184 }
185 }
186 }
187
188};
189