1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace AspectSharp
.Lang
.Steps
.Semantic
18 using System
.Collections
;
20 using AspectSharp
.Lang
.AST
;
23 /// Summary description for SemanticAnalizerStep.
25 public class SemanticAnalizerStep
: SemanticAnalizerBase
27 private IDictionary _aspectNames
= new Hashtable();
28 private IDictionary _globalMixins
;
29 private IDictionary _globalInterceptors
;
31 public override void Process(Context context
, EngineConfiguration conf
)
35 CheckImports(conf
.Imports
);
37 CheckAspects(conf
.Aspects
);
39 if (!context
.HasErrors
)
41 base.Process(context
, conf
);
45 private void CheckGlobals(EngineConfiguration conf
)
47 CheckMixins(conf
.Mixins
.ToDictionary());
48 CheckInterceptors(conf
.Interceptors
.ToDictionary());
51 private void CheckMixins(IDictionary types
)
53 AssertEntriesAreValid(types
);
54 _globalMixins
= types
;
57 private void CheckInterceptors(IDictionary types
)
59 AssertEntriesAreValid(types
);
60 _globalInterceptors
= types
;
63 private void CheckAspects(AspectDefinitionCollection aspects
)
65 foreach(AspectDefinition aspect
in aspects
)
67 AssertUnique( _aspectNames
, aspect
, aspect
.Name
, "The name given to an aspect must be unique" );
68 AssertNotNull( aspect
, aspect
.TargetType
, "Aspect must have a target type" );
69 CheckIncludes( aspect
.Mixins
);
70 CheckPointcuts( aspect
.PointCuts
);
74 private void CheckPointcuts(PointCutDefinitionCollection cuts
)
76 IDictionary pointcutsDefined
= new Hashtable();
78 foreach( PointCutDefinition pointcut
in cuts
)
80 AssertUnique( pointcutsDefined
, pointcut
, pointcut
, "Duplicated pointcut definition found" );
82 if (pointcut
.Flags
== (PointCutFlags
.Property
| PointCutFlags
.PropertyRead
) ||
83 pointcut
.Flags
== (PointCutFlags
.Property
| PointCutFlags
.PropertyWrite
))
85 RaiseErrorEvent(pointcut
.LexicalInfo
, "Meaningless declaration. A pointcut to a property can't be combined with property read or write. This is implied");
88 CheckAdvices(pointcut
.Advices
);
92 private void CheckAdvices(InterceptorDefinitionCollection advices
)
94 IDictionary advicesDefined
= new Hashtable();
96 foreach(InterceptorDefinition advice
in advices
)
98 if (advice
.TypeReference
.TargetType
== TargetTypeEnum
.Link
)
100 AssertKeyExists( _globalInterceptors
, advice
, advice
.TypeReference
.LinkRef
, "The referenced interceptor is not declared in the global interceptor section" );
103 AssertUnique( advicesDefined
, advice
, advice
.TypeReference
.ToString(), "Duplicated advices found" );
107 private void CheckIncludes( MixinDefinitionCollection includes
)
109 IDictionary names
= new Hashtable();
111 foreach( MixinDefinition type
in includes
)
113 AssertNotNull( type
, type
.TypeReference
.ToString(), "Type name must be specified as as 'Typename in AssemblyName' or as a reference to a global type declared" );
115 if (type
.TypeReference
.TargetType
== TargetTypeEnum
.Link
)
117 AssertKeyExists( _globalMixins
, type
, type
.TypeReference
.LinkRef
, "The referenced mixin is not declared in the global mixins section" );
120 AssertUnique( names
, type
, type
.TypeReference
.ToString(), "You shouldn't include the same mixin more than one time" );
124 private void CheckImports(ImportDirectiveCollection imports
)
126 // Nothing to do .. yet