protected void LoadAdviceArgs(PointCut pc) { foreach (var arg in _effect.Arguments.OrderBy(a => a.Parameter.Index)) { switch (arg.Source) { case Source.Arguments: LoadArgumentsArgument(pc, arg); break; //case Source.Attributes: LoadAttributesArgument(pc, arg); break; case Source.Instance: LoadInstanceArgument(pc, arg); break; case Source.Method: LoadMethodArgument(pc, arg); break; case Source.Name: LoadNameArgument(pc, arg); break; case Source.ReturnType: LoadReturnTypeArgument(pc, arg); break; case Source.ReturnValue: LoadReturnValueArgument(pc, arg); break; case Source.Target: LoadTargetArgument(pc, arg); break; case Source.Type: LoadTypeArgument(pc, arg); break; default: _log.LogError(CompilationMessage.From($"Unknown argument source {arg.Source.ToString()}", _target)); break; } } }
protected override void VisitVariable(VariableNode nodes) { IScope scope = nodes.FindFirstScope(); TypeInformation[] decl = scope.FindSymbol(nodes.Name); if (decl == null || decl.Length == 0) { //TODO: Edit lenght on everything... _messages.Add(CompilationMessage.Create(_data.TokenStream, nodes.Interval, MessageCode.NoSuchSymbol, _data.Filename, null)); } else if (decl.Length == 1) { //TODO: If TypeInformation needs a ScopeType that contains MethodLine and ClassLike. Supress for classLike if (decl[0].DeclarationLocation > nodes.Interval.a && decl[0].DeclaringScope == DeclaringScope.MethodLike) { //TODO: Make CompilationMessage.Create take an IntervalSet of intresting locations instead of one location... _messages.Add(CompilationMessage.Create(_data.TokenStream, nodes.Interval, MessageCode.UseBeforeDecleration, _data.Filename, null)); } } else //if(decl.Length > 1) { _messages.Add(CompilationMessage.Create(_data.TokenStream, nodes.Interval, MessageCode.InternalCompilerError, _data.Filename, "Not allowed due technical (lazy) reasons", MessageSeverity.Fatal)); } base.VisitVariable(nodes); }
private void CheckInstructionReferencesBroker(Instruction instruction) { if (instruction.OpCode == OpCodes.Ldtoken || instruction.OpCode == OpCodes.Isinst || instruction.OpCode == OpCodes.Castclass || instruction.OpCode == OpCodes.Box || instruction.OpCode == OpCodes.Newarr) { TypeReference type = instruction.Operand as TypeReference; if (type != null) { if (type.BelongsToAssembly(BrokerKeyToken) || IsGenericInstanceArgumentsReferenceBroker(type as GenericInstanceType)) { _log.LogError(CompilationMessage.From("Types from AspectInjector.Broker can't be referenced", instruction)); } } } if (instruction.OpCode == OpCodes.Ldtoken || instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Callvirt || instruction.OpCode == OpCodes.Newobj) { MethodReference method = instruction.Operand as MethodReference; if (method != null) { if (method.DeclaringType.BelongsToAssembly(BrokerKeyToken) || IsGenericInstanceArgumentsReferenceBroker(method as GenericInstanceMethod)) { _log.LogError(CompilationMessage.From("Types from AspectInjector.Broker can't be referenced", instruction)); } } } }
public void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) { AnyErrors = true; CrawlParser parser = (CrawlParser)recognizer; IntervalSet set = parser.GetExpectedTokens(); string help = $"Symbolet {CrawlLexer.ruleNames[offendingSymbol.Type]} er ikke tilladt på dette punkt. En af de følgende var forventet:\n\t" + string.Join("\n\t", set.ToArray().Select(x => parser.Vocabulary.GetDisplayName(x))); int intrestinglocation = offendingSymbol.TokenIndex; //for (int i = intrestinglocation; i < offendingSymbol.TokenIndex + 20; i++) //{ // if (parser.TokenStream.Get(i).Channel == Lexer.DefaultTokenChannel) // { // intrestinglocation = i; // break; // } //} Errors.Add(CompilationMessage.Create( parser.TokenStream, Interval.Of(intrestinglocation, intrestinglocation), MessageCode.UnexpectedSymbol, $"{_file}:{line},{charPositionInLine}", help, MessageSeverity.Error)); }
private IReadOnlyCollection <AdviceEffectBase> Extract(MethodDefinition method) { var advices = new List <AdviceEffectBase>(); foreach (var ca in method.CustomAttributes.ToList()) { if (ca.AttributeType.IsTypeOf(typeof(Broker.Advice))) { method.CustomAttributes.Remove(ca); var adviceType = ca.GetConstructorValue <Broker.Advice.Type>(0); var advice = CreateEffect(adviceType); if (advice == null) { _log.LogError(CompilationMessage.From($"Unknown advice type {adviceType.ToString()}", method)); continue; } advice.Method = method; advice.Target = ca.GetConstructorValue <Target>(1); advice.Arguments = ExtractArguments(method); advices.Add(advice); } } return(advices); }
private List <AdviceArgument> ExtractArguments(MethodDefinition method) { var args = new List <AdviceArgument>(); foreach (var par in method.Parameters) { var argAttr = par.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.IsTypeOf(typeof(Argument))); if (argAttr == null) { _log.LogError(CompilationMessage.From("Unbound arguments are not supported.", method)); continue; } par.CustomAttributes.Remove(argAttr); args.Add(new AdviceArgument { Source = argAttr.GetConstructorValue <Argument.Source>(0), Parameter = par }); } return(args); }
public override void WriteMessage(Issue issue) { var message = issue.Message; if (_includeSourceInMessage) { message = string.Format("[{0}] {1}", issue.Source, message); } string category = "information"; switch (issue.Severity) { case IssueSeverity.Error: category = "error"; break; case IssueSeverity.Warning: category = "warning"; break; } string filePath = issue.FilePath.Replace(issue.Project + @"\", string.Empty); _logger.Debug("Send compilation message to AppVeyor:"); _logger.Debug("Message: {0}", message); _logger.Debug("Category: {0}", category); _logger.Debug("FileName: {0}", filePath); _logger.Debug("Line: {0}", issue.Line); _logger.Debug("ProjectName: {0}", issue.Project); using (var httpClient = _httpClientFactory.Create()) { httpClient.BaseAddress = new Uri(_appVeyorAPIUrl); var compilationMessage = new CompilationMessage { Message = message, Category = category, FileName = filePath, Line = issue.Line, ProjectName = issue.Project }; if (issue.Offset != null) { //_logger.Debug("Column: {0}", issue.Offset.Start); //compilationMessage.Column = issue.Offset.Start; } var response = httpClient.PostAsJsonAsync("api/build/compilationmessages", compilationMessage).Result; if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NoContent) { _logger.Error("An error is occurred during the call to AppVeyor API: {0}", response); } } }
private void CheckMethodBodyReferencesBroker(MethodBody methodBody) { if (methodBody.Variables.Any(v => v.VariableType.BelongsToAssembly(BrokerKeyToken))) { _log.LogError(CompilationMessage.From("Types from AspectInjector.Broker can't be referenced", methodBody.Method)); } methodBody.Instructions.ToList().ForEach(CheckInstructionReferencesBroker); }
private void AddMessage(Diagnostic diagnostic) { var messageType = RoslynConvert.ConvertMessageType(diagnostic.Severity); var textSpan = RoslynConvert.ConvertTextSpan(diagnostic.Location.SourceSpan); var message = new CompilationMessage(messageType, textSpan, diagnostic.GetMessage()); _messages.Add(message); }
public virtual void LogWarning(CompilationMessage message) { if (message.SequencePoint?.Document != null) { Write($"{message.SequencePoint.Document.Url}({message.SequencePoint.StartLine},{message.SequencePoint.StartColumn},{message.SequencePoint.EndLine},{message.SequencePoint.EndColumn}): ", MessageType.Warning); } WriteLine($"Warning: { message.Text}", MessageType.Warning); }
public void Weave(Injection injection) { var effect = (AdviceEffectBase)injection.Effect; if (injection.Target is EventDefinition) { var target = (EventDefinition)injection.Target; if (target.AddMethod != null && effect.Target.HasFlag(Target.EventAdd)) { WeaveMethod(target.AddMethod, injection); } if (target.RemoveMethod != null && effect.Target.HasFlag(Target.EventRemove)) { WeaveMethod(target.RemoveMethod, injection); } return; } if (injection.Target is PropertyDefinition) { var target = (PropertyDefinition)injection.Target; if (target.SetMethod != null && effect.Target.HasFlag(Target.Setter)) { WeaveMethod(target.SetMethod, injection); } if (target.GetMethod != null && effect.Target.HasFlag(Target.Getter)) { WeaveMethod(target.GetMethod, injection); } return; } if (injection.Target is MethodDefinition) { var target = (MethodDefinition)injection.Target; if (target.IsConstructor && effect.Target.HasFlag(Target.Constructor)) { WeaveMethod(target, injection); } if (target.IsNormalMethod() && effect.Target.HasFlag(Target.Method)) { WeaveMethod(target, injection); } return; } _log.LogError(CompilationMessage.From($"Unsupported target {injection.Target.GetType().Name}", injection.Target)); }
public CompilationFailedException(SerializationInfo info, StreamingContext context) : base(info, context) { GeneratedCode = info.GetString("GeneratedCode"); var messages = new CompilationMessage[info.GetInt32("Messages.Count")]; for (int i = 0; i < messages.Length; i++) { messages[i] = (CompilationMessage)info.GetValue("Messages[" + i + "]", typeof(CompilationMessage)); } Messages = messages.ToList(); }
/// <summary> /// Executes the module builder process /// </summary> /// <param name="context">The compilation context.</param> public void Execute(CompilationContext context) { if (context.Input == null) { throw new CompilationException("The compilation input cannot be null."); } // ensure the output directory is available if (!Directory.Exists(context.Input.TargetDirectory)) { Directory.CreateDirectory(context.Input.TargetDirectory); } CompilerResults compileResult = null; using (var codeProvider = new CSharpCodeProvider()) { // create compiler and options var options = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true, IncludeDebugInformation = false, CompilerOptions = "/t:library /noconfig /nostdlib" }; // add referenced assemblies options.ReferencedAssemblies.AddRange( context.Input.ReferencePaths.ToArray()); // compile to module compileResult = codeProvider.CompileAssemblyFromFile(options, context.Input.SourceFilePaths.ToArray()); } // check for errors or warnings foreach (var item in compileResult.Errors.OfType <CompilerError>()) { var msg = new CompilationMessage { FilePath = item.FileName, Message = item.ErrorText }; if (item.IsWarning) { context.Result.AddWarning(msg); } else { context.Result.AddError(msg); } } }
public virtual void LogError(CompilationMessage message) { if (message.SequencePoint?.Document != null) { Write($"{message.SequencePoint.Document.Url}({message.SequencePoint.StartLine},{message.SequencePoint.StartColumn},{message.SequencePoint.EndLine},{message.SequencePoint.EndColumn}): ", MessageType.Error); } WriteLine($"Error: { message.Text}", MessageType.Error); IsErrorThrown = true; }
private void CheckAttributesReferencesBrocker(ICustomAttributeProvider provider) { //todo:: check constructors, firlds, properties foreach (var attr in provider.CustomAttributes) { if (attr.AttributeType.BelongsToAssembly(BrokerKeyToken)) { _log.LogError(CompilationMessage.From("Types from AspectInjector.Broker can't be referenced", provider)); } } }
private void CheckTypeReferencesBroker(TypeDefinition type) { type.Methods.ToList().ForEach(CheckMethodReferencesBroker); if ((type.BaseType != null && (type.BaseType.BelongsToAssembly(BrokerKeyToken) || IsGenericInstanceArgumentsReferenceBroker(type.BaseType as IGenericInstance))) || type.Fields.Any(f => f.FieldType.BelongsToAssembly(BrokerKeyToken) || IsGenericInstanceArgumentsReferenceBroker(f.FieldType as IGenericInstance)) || IsGenericParametersReferenceBroker(type)) { _log.LogError(CompilationMessage.From("Types from AspectInjector.Broker can't be referenced", type)); } type.NestedTypes.ToList().ForEach(CheckTypeReferencesBroker); }
private void AddError(string message, SyntaxNode node = null) { var msg = new CompilationMessage(); msg.Message = message; if (Semantics != null && Semantics.SyntaxTree != null) { msg.FilePath = Semantics.SyntaxTree.FilePath; msg.Location = DocumentLocation.FromTreeNode(Semantics.SyntaxTree, node); } _errors.Add(msg); }
public override bool Validate(AspectDefinition aspect, ILogger log) { if (Method.IsStatic) { log.LogError(CompilationMessage.From($"Advice {Method.FullName} cannot be static.", aspect.Host)); return(false); } if (!Method.IsPublic) { log.LogError(CompilationMessage.From($"Advice {Method.FullName} should be public.", aspect.Host)); return(false); } return(true); }
public override bool Validate(AspectDefinition aspect, ILogger log) { if (!InterfaceType.Resolve().IsInterface) { log.LogError(CompilationMessage.From($"{InterfaceType.FullName} is not an interface.", aspect.Host)); return(false); } if (!aspect.Host.Implements(InterfaceType)) { log.LogError(CompilationMessage.From($"{aspect.Host.FullName} should implement {InterfaceType.FullName}.", aspect.Host)); return(false); } return(true); }
public void ProcessAssembly(AssemblyDefinition assembly) { var aspects = _aspectExtractor.Extract(assembly); foreach (var aspect in aspects) { _cache.Cache(aspect); } var injections = _injectionCollector.Collect(assembly).ToList(); _janitor.Cleanup(assembly); if (_log.IsErrorThrown) { return; } _cache.FlushCache(assembly); foreach (var aspect in aspects) { _assectWeaver.WeaveGlobalAssests(aspect); } foreach (var injector in _effectWeavers.OrderByDescending(i => i.Priority)) { _log.LogInfo($"Executing {injector.GetType().Name}"); foreach (var prioritizedInjections in injections.GroupBy(i => i.Priority).OrderByDescending(a => a.Key).ToList()) { foreach (var injection in prioritizedInjections.OrderByDescending(i => i.Effect.Priority)) { if (injector.CanWeave(injection)) { injector.Weave(injection); injections.Remove(injection); } } } } foreach (var injection in injections) { _log.LogError(CompilationMessage.From($"Couldn't find weaver for {injection.ToString()}", injection.Target)); } }
protected override CrawlSyntaxNode VisitType(TypeNode type) { IScope scope = type.FindFirstScope(); try { CrawlType actualType = CrawlType.ParseDecleration(scope, type.TypeName); var v = type.WithActualType(actualType); return(v); } catch (TypeNotFoundException tnfe) { _messages.Add(CompilationMessage.Create(_tokens, type.Interval, MessageCode.TypeNotFound, _file)); return(type); } }
private void CheckMethodReferencesBroker(MethodDefinition method) { if (method.Parameters.Any(p => p.ParameterType.BelongsToAssembly(BrokerKeyToken) || IsGenericInstanceArgumentsReferenceBroker(p.ParameterType as IGenericInstance)) || method.ReturnType.BelongsToAssembly(BrokerKeyToken) || IsGenericParametersReferenceBroker(method) || IsGenericInstanceArgumentsReferenceBroker(method.ReturnType as IGenericInstance) ) { _log.LogError(CompilationMessage.From("Types from AspectInjector.Broker can't be referenced", method)); } if (method.Body != null) { CheckMethodBodyReferencesBroker(method.Body); } }
/// <summary> /// Executes the module builder process /// </summary> /// <param name="context">The compilation context.</param> public void Execute(CompilationContext context) { if (context.Input == null) throw new CompilationException("The compilation input cannot be null."); // ensure the output directory is available if (!Directory.Exists(context.Input.TargetDirectory)) Directory.CreateDirectory(context.Input.TargetDirectory); CompilerResults compileResult = null; using (var codeProvider = new CSharpCodeProvider()) { // create compiler and options var options = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true, IncludeDebugInformation = false, CompilerOptions = "/t:library /noconfig /nostdlib" }; // add referenced assemblies options.ReferencedAssemblies.AddRange( context.Input.ReferencePaths.ToArray()); // compile to module compileResult = codeProvider.CompileAssemblyFromFile(options, context.Input.SourceFilePaths.ToArray()); } // check for errors or warnings foreach (var item in compileResult.Errors.OfType<CompilerError>()) { var msg = new CompilationMessage { FilePath = item.FileName, Message = item.ErrorText }; if (item.IsWarning) context.Result.AddWarning(msg); else context.Result.AddError(msg); } }
private IEnumerable <Injection> ParseInjectionAttribute(ICustomAttributeProvider target, CustomAttribute attr) { var aspectRef = attr.GetConstructorValue <TypeReference>(0); var aspect = _cache.ReadAspect(aspectRef.Resolve()); if (aspect == null) { _log.LogError(CompilationMessage.From($"Type {aspectRef.FullName} should be an aspect class.", target)); return(Enumerable.Empty <Injection>()); } var priority = attr.GetPropertyValue <Broker.Inject, ushort>(i => i.Priority); // var childFilter = attr.GetPropertyValue<Broker.Inject, InjectionChildFilter>(i => i.Filter); var injections = FindApplicableMembers(target, aspect, priority /*, childFilter*/); return(injections); }
public int Execute(IReadOnlyList <string> args) { if (args.Count == 0) { ShowHelp(); return(-1); } var filename = args[0]; var optimize = args[1] == "-o"; var refsStart = optimize ? 2 : 1; var references = new ArraySegment <string>(args.ToArray(), refsStart, args.Count - refsStart); if (!File.Exists(filename)) { ShowHelp($"File {filename} does not exist."); return(1); } var log = new ConsoleLogger(); var processor = CreateProcessor(log); var resolver = new KnownReferencesAssemblyResolver(); resolver.AddSearchDirectory(Path.GetDirectoryName(filename)); references.ToList().ForEach(resolver.AddReference); try { processor.Process(filename, resolver, optimize); } catch (Exception e) { log.LogError(CompilationMessage.From(e.ToString())); } return(log.IsErrorThrown ? 1 : 0); }
void CheckHides(CrawlSyntaxNode aScope) { //TODO: This should be optimized by adding and removing from mapping with a stack //Would go from O(n^2) -> O(1) //This checks if something gets redefined. Dictionary <string, CrawlSyntaxNode> mapping = new Dictionary <string, CrawlSyntaxNode>(); while (aScope != null) { IScope scope = aScope as IScope; if (scope != null) { var local = scope.LocalSymbols(); //TODO: REMOVE. Just to stop it crashing if (local == null) { local = new List <string>(); } foreach (string symbol in local) { if (mapping.ContainsKey(symbol)) { Interval first = mapping[symbol].Interval; _messages.Add(CompilationMessage.Create(_data.TokenStream, first, MessageCode.HidesOtherSymbol, _data.Filename, $"Unable to declare {symbol} as it hides {symbol} from {aScope}")); } else { mapping.Add(symbol, aScope); } } } aScope = aScope.Parent; } }
public override bool Validate(AspectDefinition aspect, ILogger log) { if (Method.IsStatic) { log.LogError(CompilationMessage.From($"Advice {Method.FullName} cannot be static.", aspect.Host)); return(false); } if (!Method.IsPublic) { log.LogError(CompilationMessage.From($"Advice {Method.FullName} should be public.", aspect.Host)); return(false); } if (Method.ReturnType != Method.Module.TypeSystem.Object) { log.LogError(CompilationMessage.From($"Around advice {Method.FullName} should return an object. Could return null.", aspect.Host)); return(false); } return(true); }
public AstData AddExport(AstData arg, SideeffectHelper helper) { var tu = ((TranslationUnitNode)arg.Tree.RootNode); try { return(new AstData( arg.TokenStream, arg.Filename, tu .WithImportedNamespaces( Namespace.Merge(tu.Imports.Select(TryGetNamespace).ToArray()) ) .OwningTree )); } catch (NamespaceNotFoundException nsnfe) { throw helper.FailWith(CompilationMessage.Create(arg.TokenStream, nsnfe.FaultyNode.Interval, MessageCode.NamespaceNotFound, arg.Filename)); } }
public AspectDefinition ReadAspect(TypeDefinition type) { var effects = ExtractEffects(type).ToList(); var aspect = ExtractAspectAttribute(type); if (aspect != null) { return new AspectDefinition { Host = type, Scope = aspect.GetConstructorValue <Aspect.Scope>(0), Factory = aspect.GetPropertyValue <Aspect>(au => au.Factory) as TypeReference, Effects = effects } } ; if (effects.Any()) { _log.LogError(CompilationMessage.From($"Type {type.FullName} has effects, but is not marked as an aspect. Concider using [Aspect] attribute.", type)); } return(null); }
protected virtual void LoadReturnValueArgument(PointCut pc, AdviceArgument parameter) { _log.LogWarning(CompilationMessage.From($"Advice {_effect.Type.ToString()} does not support {parameter.Source.ToString()} argument and will always return null", _effect.Method)); pc.Null(); }
public virtual void Print(CompilationMessage message) { _messager.printMessage(message.Category, message.Contents, message.Element, message.Mirror); }
public override void WriteMessage(Issue issue) { var message = issue.Message; if (IncludeSourceInMessage) { message = string.Format("[{0}] {1}", issue.Source, message); } string category = "information"; switch (issue.Severity) { case IssueSeverity.Error: category = "error"; break; case IssueSeverity.Warning: category = "warning"; break; } string filePath = issue.FilePath.Replace(issue.Project + @"\", string.Empty); string details = string.Format("{0} in {1} on line {2}", message, filePath, issue.Line); _logger.Debug("Send compilation message to AppVeyor:"); _logger.Debug("Message: {0}", message); _logger.Debug("Category: {0}", category); _logger.Debug("FileName: {0}", filePath); _logger.Debug("Line: {0}", issue.Line); _logger.Debug("ProjectName: {0}", issue.Project); _logger.Debug("Details: {0}", details); using (var httpClient = _httpClientFactory.Create()) { httpClient.BaseAddress = new Uri(_appVeyorApiUrl); var compilationMessage = new CompilationMessage { Message = message, Category = category, FileName = filePath, Line = issue.Line, ProjectName = issue.Project, Details = details }; if (issue.Offset != null) { _logger.Debug("Column: {0}", issue.Offset.Start); compilationMessage.Column = issue.Offset.Start + 1; } JsonMediaTypeFormatter jsonFormat = new JsonMediaTypeFormatter(); jsonFormat.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore; jsonFormat.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; var response = httpClient.PostAsync("api/build/compilationmessages", compilationMessage, jsonFormat).Result; if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NoContent) { _logger.Error("An error is occurred during the call to AppVeyor API: {0}", response); } } }