1 /*
2  *Copyright (C) 2018 Laurent Tréguier
3  *
4  *This file is part of DLS.
5  *
6  *DLS is free software: you can redistribute it and/or modify
7  *it under the terms of the GNU General Public License as published by
8  *the Free Software Foundation, either version 3 of the License, or
9  *(at your option) any later version.
10  *
11  *DLS is distributed in the hope that it will be useful,
12  *but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *GNU General Public License for more details.
15  *
16  *You should have received a copy of the GNU General Public License
17  *along with DLS.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 module dls.tools.configuration;
22 
23 class Configuration
24 {
25     import std.json : JSONValue;
26 
27     static class SymbolConfiguration
28     {
29         string[] importPaths;
30         bool listLocalSymbols;
31     }
32 
33     static class AnalysisConfiguration
34     {
35         string configFile = "dscanner.ini";
36     }
37 
38     static class FormatConfiguration
39     {
40         static enum BraceStyle : string
41         {
42             allman = "allman",
43             otbs = "otbs",
44             stroustrup = "stroustrup"
45         }
46 
47         static enum EndOfLine : string
48         {
49             lf = "lf",
50             cr = "cr",
51             crlf = "crlf"
52         }
53 
54         static enum TemplateConstraintStyle : string
55         {
56             conditionalNewlineIndent = "conditionalNewlineIndent",
57             conditionalNewline = "conditionalNewline",
58             alwaysNewline = "alwaysNewline",
59             alwaysNewlineIndent = "alwaysNewlineIndent"
60         }
61 
62         EndOfLine endOfLine = EndOfLine.lf;
63         int maxLineLength = 120;
64         bool dfmtAlignSwitchStatements = true;
65         BraceStyle dfmtBraceStyle = BraceStyle.allman;
66         bool dfmtOutdentAttributes = true;
67         int dfmtSoftMaxLineLength = 80;
68         bool dfmtSpaceAfterCast = true;
69         bool dfmtSpaceAfterKeywords = true;
70         bool dfmtSpaceBeforeFunctionParameters = false;
71         bool dfmtSplitOperatorAtLineEnd = false;
72         bool dfmtSelectiveImportSpace = true;
73         bool dfmtCompactLabeledStatements = true;
74         TemplateConstraintStyle dfmtTemplateConstraintStyle = TemplateConstraintStyle
75             .conditionalNewlineIndent;
76         bool dfmtSingleTemplateConstraintIndent = false;
77     }
78 
79     SymbolConfiguration symbol;
80     AnalysisConfiguration analysis;
81     FormatConfiguration format;
82 
83     this()
84     {
85         symbol = new SymbolConfiguration();
86         analysis = new AnalysisConfiguration();
87         format = new FormatConfiguration();
88     }
89 
90     void merge(JSONValue json)
91     {
92         merge!(typeof(this))(json);
93     }
94 
95     private void merge(T)(JSONValue json)
96     {
97         import dls.util.json : convertFromJSON;
98         import std.json : JSON_TYPE;
99         import std.meta : Alias;
100         import std.traits : isSomeFunction, isType;
101 
102         if (json.type != JSON_TYPE.OBJECT)
103         {
104             return;
105         }
106 
107         foreach (member; __traits(allMembers, T))
108         {
109             if (member !in json)
110             {
111                 continue;
112             }
113 
114             alias m = Alias!(__traits(getMember, T, member));
115 
116             static if (!isType!(m) && !isSomeFunction!(m))
117             {
118                 static if (is(m == class))
119                 {
120                     merge(m, json[member]);
121                 }
122                 else
123                 {
124                     m = convertFromJSON!(typeof(m))(json[member]);
125                 }
126             }
127         }
128     }
129 }