Better handling of complex primary key params.
[castle.git] / AspectSharp / AspectSharp.Lang / langparser.g
blobcf3475106868356a4c36d9a0369361dfe8990899
1 header\r
2 {\r
3     using antlr;\r
4     using System.Text;\r
5     using AspectSharp.Lang.AST;\r
6 }\r
7 options \r
8 {\r
9         language = "CSharp";\r
10 }\r
11 class AspectLanguageParser extends Parser;\r
12 options \r
13 {\r
14     buildAST = false;\r
15     exportVocab=aspectLanguage;\r
16     defaultErrorHandler = true;\r
17 }\r
18 tokens \r
19 {\r
20         ASPECT="aspect"; \r
21         FOR="for";\r
22         IN="in";\r
23         END="end";\r
24         IMPORT="import"; \r
25         MIXINS="mixins"; \r
26         INCLUDE="include"; \r
27         INTERCEPTORS="interceptors"; \r
28         ADVICEINTERCEPTOR="advice";\r
29         POINTCUT="pointcut";\r
30         METHOD="method";\r
31         PROPERTY="property";\r
32         PROPERTY_READ="propertyread";\r
33         PROPERTY_WRITE="propertywrite";\r
34         ASSIGNFROM="assignableFrom";\r
35         CUSTOMMATCHER="customMatcher";\r
36         EXCLUDES="excludes";\r
37         INCLUDES="includes";\r
38 }\r
39 {\r
40     protected StringBuilder sbuilder = new StringBuilder();\r
42         protected LexicalInfo ToLexicalInfo(antlr.Token token)\r
43         {\r
44                 int line = token.getLine();\r
45                 int startColumn = token.getColumn();\r
46                 int endColumn = token.getColumn() + token.getText().Length;\r
47                 String filename = token.getFilename();\r
48                 return new LexicalInfo(filename, line, startColumn, endColumn);\r
49         }\r
51     protected String methodAll(String s)\r
52    {\r
53         if (s == "*")\r
54             return ".*";\r
55         return s;   \r
56     }\r
57 }\r
60 start returns [EngineConfiguration conf]\r
61         {\r
62                 conf = new EngineConfiguration();               \r
63         }:\r
64         (options { greedy=true;}: EOS!)*                         \r
65         (import_directive[conf])*\r
66         (interceptors_global[conf])*\r
67         (mixins_global[conf])*\r
68         (aspects[conf])*\r
69         EOF!\r
70         ;\r
72 protected\r
73 import_directive[EngineConfiguration conf]\r
74         {\r
75                 String ns;\r
76                 String assemblyName;\r
77                 ImportDirective import = null;\r
78         }: \r
79         i:IMPORT! ns=identifier!\r
80         {\r
81                 import = new ImportDirective( ToLexicalInfo(i), ns );\r
82                 conf.Imports.Add(import);\r
83         }\r
84         (\r
85             IN! assemblyName=identifier!\r
86             {\r
87                 import.AssemblyReference = new AssemblyReference( ToLexicalInfo(i), assemblyName);\r
88             }\r
89         )?\r
90         ;\r
91         \r
92 protected\r
93 interceptors_global[EngineConfiguration conf] :\r
94     INTERCEPTORS! keytypepair[conf.Interceptors]\r
95     {\r
96     }\r
97     ;\r
99 protected\r
100 mixins_global[EngineConfiguration conf] :\r
101     MIXINS! keytypepair[conf.Mixins]\r
102     {\r
103     }\r
104     ;\r
105     \r
106 protected\r
107 keytypepair [IDeclarationCollection collection] :\r
108     LBRACK!\r
109     (\r
110         (pairvalue[collection] (SEMI pairvalue[collection])*)\r
111     )\r
112     RBRACK!\r
113     ;\r
115 protected \r
116 pairvalue [IDeclarationCollection collection] \r
117     {\r
118         DefinitionBase definition = null;\r
119     } :\r
120     keyToken:STRING_LITERAL! COLON \r
121     {\r
122         String key = keyToken.getText();\r
123         definition = collection.Add( key, ToLexicalInfo(keyToken) );\r
124     }\r
125     type_name[definition]\r
126     ;\r
128 protected \r
129 type_name_or_ref returns [TypeReference type] \r
130     {\r
131         type = null;\r
132     } :\r
133     refTypeToken:STRING_LITERAL!\r
134     {\r
135         type = new TypeReference();\r
136         type.LinkRef = refTypeToken.getText();\r
137     }\r
138     |\r
139     type=type_name_def!\r
140     ;\r
142 protected\r
143 type_name[DefinitionBase definition]\r
144     {\r
145         TypeReference tr = null;\r
146     } :\r
147     tr=type_name_def!\r
148     {\r
149         definition.TypeReference = tr;\r
150     }\r
151     ;\r
153 protected\r
154 type_name_def returns [TypeReference type] \r
155     {\r
156         type = new TypeReference();\r
157         String typeToken = null;\r
158         String assemblyToken = null;\r
159     } :\r
160     typeToken=identifier!\r
161     {\r
162         type.TypeName = typeToken;\r
163     }\r
164     (\r
165         i:IN! assemblyToken=identifier!\r
166         {\r
167             type.AssemblyReference = new AssemblyReference( ToLexicalInfo(i), assemblyToken );\r
168         }\r
169     )?\r
170     ;\r
171     \r
172 protected\r
173 aspects [EngineConfiguration conf]\r
174     {\r
175         AspectDefinition aspect = null;\r
176         TargetTypeDefinition target = null;\r
177         TypeReference tr = null;\r
178     } :\r
179     a:ASPECT! aspectId:ID FOR! \r
180     {\r
181         aspect = new AspectDefinition( ToLexicalInfo(a), aspectId.getText() );\r
182         conf.Aspects.Add(aspect);\r
183     }\r
184     (\r
185         tr=type_name_def!\r
186         {\r
187             target = new TargetTypeDefinition( tr );\r
188             target.TargetStrategy = TargetStrategyEnum.SingleType;\r
189             aspect.TargetType = target;\r
190         }\r
191         |\r
192         LBRACK! \r
193         {\r
194             target = new TargetTypeDefinition( );\r
195             aspect.TargetType = target;\r
196             String namespaceRegEx = null;\r
197         }\r
198         (\r
199             ASSIGNFROM LCURLY! tr=type_name_def! RCURLY!\r
200             {\r
201                 target.TargetStrategy = TargetStrategyEnum.Assignable;\r
202                 target.AssignType = tr;\r
203             }\r
204             |\r
205             CUSTOMMATCHER LCURLY! tr=type_name_def! RCURLY!\r
206             {\r
207                 target.TargetStrategy = TargetStrategyEnum.Custom;\r
208                 target.CustomMatcherType = tr;\r
209             }\r
210             |\r
211             (\r
212                 namespaceRegEx=identifier \r
213                 {\r
214                     target.TargetStrategy = TargetStrategyEnum.Namespace;\r
215                     target.NamespaceRoot = namespaceRegEx;\r
216                 }\r
217                 (\r
218                     EXCLUDES LCURLY type_list[target.Excludes] RCURLY\r
219                 )?\r
220             )\r
221         )\r
222         RBRACK!\r
223     )\r
224     (\r
225         (include[aspect])*\r
226         (pointcut[aspect])*\r
227     )\r
228     END!\r
229     ;\r
231 protected \r
232 type_list [TypeReferenceCollection types] \r
233     {\r
234         TypeReference tr = null;\r
235     }:\r
236     tr=type_name_def!\r
237     {\r
238         types.Add(tr);\r
239     }\r
240     (\r
241         SEMI! tr=type_name_def!\r
242         {\r
243             types.Add(tr);\r
244         }\r
245     )*\r
246     ;\r
248 protected\r
249 include [AspectDefinition aspect]\r
250     {\r
251         TypeReference tr = null;\r
252         MixinDefinition md;\r
253     }:\r
254     i:INCLUDE!\r
255     {\r
256         md = new MixinDefinition( ToLexicalInfo(i) );\r
257     }\r
258     tr=type_name_or_ref!\r
259     {\r
260         md.TypeReference = tr;\r
261         aspect.Mixins.Add( md );\r
262     }\r
263     ;\r
265 protected \r
266 pointcut [AspectDefinition aspect]\r
267     {\r
268         PointCutDefinition pointcut = null;\r
269         PointCutFlags flags = PointCutFlags.Unspecified;\r
270     } :\r
271     p:POINTCUT! flags=pointcutflags \r
272     {\r
273         pointcut = new PointCutDefinition( ToLexicalInfo(p), flags );\r
274         aspect.PointCuts.Add( pointcut );\r
275     }\r
276     pointcuttarget[pointcut]\r
277     advices[pointcut]\r
278     END!\r
279     ;\r
281 protected\r
282 advices [PointCutDefinition pointcut] :\r
283     (advice[pointcut])*\r
284     ;\r
286 protected\r
287 advice [PointCutDefinition pointcut] \r
288     {\r
289         TypeReference tr = null;\r
290         InterceptorDefinition interDef = null;\r
291     } :\r
292     i:ADVICEINTERCEPTOR \r
293     {\r
294         interDef = new InterceptorDefinition( ToLexicalInfo(i) );\r
295     }\r
296     LCURLY tr=type_name_or_ref!\r
297     {\r
298         interDef.TypeReference = tr;\r
299         pointcut.Advices.Add( interDef );\r
300     }\r
301     RCURLY\r
302     ;\r
303     \r
304 protected\r
305 pointcutflags returns [PointCutFlags flags]\r
306     {\r
307         flags = PointCutFlags.Unspecified;\r
308     } : \r
309     flags=pointcutflag[flags] (OR flags=pointcutflag[flags])?\r
310     ;\r
312 protected\r
313 pointcutflag[PointCutFlags flags] returns [PointCutFlags retValue]\r
314     {\r
315         retValue = flags;\r
316     } :\r
317     METHOD\r
318     { retValue |= PointCutFlags.Method; }\r
319     |\r
320     PROPERTY\r
321     { retValue |= PointCutFlags.Property; }\r
322     |\r
323     PROPERTY_READ \r
324     { retValue |= PointCutFlags.PropertyRead; }\r
325     |\r
326     PROPERTY_WRITE\r
327     { retValue |= PointCutFlags.PropertyWrite; }\r
328     ;\r
330 protected\r
331 pointcuttarget [PointCutDefinition pointcut] :\r
332     LCURLY!\r
333     pointcutsignature[pointcut]\r
334 //    RCURLY!\r
335     ;\r
337  \r
338 protected\r
339 pointcutsig1 [PointCutDefinition pointcut]\r
340 \r
341     String part1;\r
342         MethodSignature ms = null;\r
343 } :\r
344 \r
345     ALL\r
346     {\r
347         part1 = "*"; \r
348         ms = AllMethodSignature.Instance;\r
349     }\r
350     |\r
351     part1 = reg_ex[true]\r
352     { ms = new MethodSignature(part1, methodAll("*")); }  \r
354 { pointcut.Method = pointcutsig2(part1, ms); }\r
355 \r
357 protected\r
358 pointcutsig2 [String part1, MethodSignature ms] returns [MethodSignature ret]\r
359 \r
360     String part2; \r
361     ret = null;\r
362 } :\r
364     ALL  { part2 = "*"; }\r
365     ret = pointcutsig3[part1, part2, ms] \r
366    |\r
367     LCURLY  \r
368             pointcutarguments[ms]\r
369     RCURLY\r
370     RCURLY \r
371     { ret = ms; }\r
372     | \r
373     RCURLY\r
374     { ret = ms; } \r
375    |\r
376     part2 = reg_ex[true] \r
377     ret = pointcutsig3[part1, part2, ms] \r
378 \r
381 protected\r
382 pointcutsig3 [String part1, String part2, MethodSignature ms] returns [MethodSignature ret]\r
383 \r
384     String part3; \r
385     ret = null;\r
386 } :\r
388     ALL { part3 = "*"; }\r
389     { ms = new MethodSignature(part1, part2, methodAll(part3)); }\r
390     pointcutsig4[ms]\r
391    |\r
392     LCURLY\r
393     { ms = new MethodSignature(part1, methodAll(part2)); }\r
394         pointcutarguments[ms]\r
395     RCURLY\r
396     RCURLY \r
397    |\r
398     RCURLY\r
399     { ms = new MethodSignature(part1, methodAll(part2)); }\r
400    |        \r
401     part3 = reg_ex[false]\r
402     { ms = new MethodSignature(part1, part2, methodAll(part3)); }  \r
403     pointcutsig4[ms] \r
404 ) { ret = ms; }\r
405 \r
407 protected\r
408 pointcutsig4 [MethodSignature ms]\r
411     LCURLY\r
412     pointcutarguments[ms]\r
413     RCURLY\r
414     RCURLY \r
415     |  \r
416     RCURLY\r
418 \r
420 protected\r
421 pointcutsignature [PointCutDefinition pointcut]\r
423     pointcutsig1[pointcut]\r
424 \r
427 protected \r
428 pointcutarguments [MethodSignature ms] :\r
429     (pointcutargument[ms] (COMMA pointcutargument[ms])*)?\r
430     ;\r
431     \r
432 protected \r
433 pointcutargument [MethodSignature ms] \r
434     {\r
435         String argType = String.Empty;\r
436     }:\r
437     ALL\r
438     {\r
439         ms.AddArgumentType( "*" );\r
440     }\r
441     |\r
442     argType=reg_ex[false]!\r
443     {\r
444         ms.AddArgumentType( argType );\r
445     }\r
446     ;\r
448 protected\r
449 identifier returns [String value]\r
450         {\r
451                 value = null; sbuilder.Length = 0;\r
452         }:                      \r
453         id:ID                   \r
454         {                                       \r
455                 sbuilder.Append(id.getText());\r
456                 value = sbuilder.ToString();\r
457         }\r
458         ( options { greedy = true; }:\r
459             DOT!\r
460             id2:ID\r
461             {\r
462                 sbuilder.Append('.');\r
463                 sbuilder.Append(id2.getText());\r
464             }\r
465         )*\r
466         {\r
467             value = sbuilder.ToString();\r
468         }\r
469         ;\r
471 protected\r
472 reg_ex [Boolean allowALL] returns [String value]\r
473         {\r
474                 value = null; sbuilder.Length = 0;\r
475         }:\r
476         ( \r
477             id:ID! \r
478             {                                   \r
479                     sbuilder.Append(id.getText());\r
480                     value = sbuilder.ToString();\r
481             }\r
482             ( options { greedy = true; }:\r
483                 WS\r
484                 |\r
485                 { if (LA(1) == ALL) {\r
486                \r
487                     if (allowALL) \r
488                         break;\r
489                     throw new NoViableAltException(LT(1), getFilename()); \r
490                    } \r
491                 }\r
492                 | \r
493                 DOT!\r
494                 {\r
495                     sbuilder.Append('.');\r
496                 }\r
497                 ALL!\r
498                 {\r
499                     sbuilder.Append('*');\r
500                 }\r
501             )?\r
502         )\r
503         {\r
504             value = sbuilder.ToString();\r
505         }\r
506         ;\r