1 /** 2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 */ 10 module dextool.plugin.analyze.filerange; 11 12 import dextool.compilation_db : CompileCommandFilter, CompileCommandDB, parseFlag; 13 import dextool.type : FileName, AbsolutePath; 14 15 @safe: 16 17 struct AnalyzeFileRange { 18 import std.typecons : Nullable; 19 import dextool.clang : findFlags; 20 import dextool.compilation_db : SearchResult; 21 22 enum RangeOver { 23 inFiles, 24 database 25 } 26 27 this(CompileCommandDB db, string[] in_files, string[] cflags, 28 const CompileCommandFilter ccFilter) { 29 this.db = db; 30 this.cflags = cflags; 31 this.ccFilter = ccFilter; 32 this.inFiles = in_files; 33 34 if (in_files.length == 0) { 35 kind = RangeOver.database; 36 } else { 37 kind = RangeOver.inFiles; 38 } 39 } 40 41 const RangeOver kind; 42 CompileCommandDB db; 43 string[] inFiles; 44 string[] cflags; 45 const CompileCommandFilter ccFilter; 46 47 Nullable!SearchResult front() { 48 assert(!empty, "Can't get front of an empty range"); 49 50 Nullable!SearchResult curr; 51 52 final switch (kind) { 53 case RangeOver.inFiles: 54 if (db.length > 0) { 55 curr = db.findFlags(FileName(inFiles[0]), cflags, ccFilter); 56 } else { 57 curr = SearchResult(cflags.dup, AbsolutePath(FileName(inFiles[0]))); 58 } 59 break; 60 case RangeOver.database: 61 import std.array : appender; 62 63 auto tmp = db.payload[0]; 64 auto flags = appender!(string[])(); 65 flags.put(cflags); 66 flags.put(tmp.parseFlag(ccFilter).completeFlags); 67 curr = SearchResult(flags.data, tmp.absoluteFile); 68 break; 69 } 70 71 return curr; 72 } 73 74 void popFront() { 75 assert(!empty, "Can't pop front of an empty range"); 76 77 final switch (kind) { 78 case RangeOver.inFiles: 79 inFiles = inFiles[1 .. $]; 80 break; 81 case RangeOver.database: 82 db.payload = db.payload[1 .. $]; 83 break; 84 } 85 } 86 87 bool empty() @safe pure nothrow const @nogc { 88 final switch (kind) { 89 case RangeOver.inFiles: 90 return inFiles.length == 0; 91 case RangeOver.database: 92 return db.length == 0; 93 } 94 } 95 96 size_t length() @safe pure nothrow const @nogc { 97 final switch (kind) { 98 case RangeOver.inFiles: 99 return inFiles.length; 100 case RangeOver.database: 101 return db.length; 102 } 103 } 104 }