| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2015 - ROLI Ltd.
 - 
 -    Permission is granted to use this software under the terms of either:
 -    a) the GPL v2 (or any later version)
 -    b) the Affero GPL v3
 - 
 -    Details of these licenses can be found at: www.gnu.org/licenses
 - 
 -    JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
 -    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 -    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 - 
 -    ------------------------------------------------------------------------------
 - 
 -    To release a closed-source product which uses JUCE, commercial licenses are
 -    available: visit www.juce.com for more information.
 - 
 -   ==============================================================================
 - */
 - 
 - struct DiagnosticMessage
 - {
 -     DiagnosticMessage() = default;
 - 
 -     DiagnosticMessage (const DiagnosticMessage& other)
 -        : associatedDiagnostic (createCopyIfNotNull (other.associatedDiagnostic.get())),
 -          message (other.message),
 -          mainFile (other.mainFile),
 -          range (other.range),
 -          type (other.type)
 -     {
 -     }
 - 
 -     DiagnosticMessage& operator= (const DiagnosticMessage& other)
 -     {
 -         associatedDiagnostic = createCopyIfNotNull (other.associatedDiagnostic.get());
 -         message = other.message;
 -         mainFile = other.mainFile;
 -         range = other.range;
 -         type = other.type;
 - 
 -         return *this;
 -     }
 - 
 -     enum Type
 -     {
 -         error = 0,
 -         warning = 1,
 -         note = 2
 -     };
 - 
 -     ScopedPointer<DiagnosticMessage> associatedDiagnostic;
 -     String message;
 -     String mainFile;
 -     SourceCodeRange range;
 -     Type type;
 - 
 -     bool isError() const noexcept       { return type == error; }
 -     bool isWarning() const noexcept     { return type == warning; }
 -     bool isNote() const noexcept        { return type == note; }
 - 
 -     ValueTree toValueTree() const
 -     {
 -         ValueTree v (MessageTypes::DIAGNOSTIC);
 -         v.setProperty (Ids::text, message, nullptr);
 -         v.setProperty (Ids::file, mainFile, nullptr);
 -         v.setProperty (Ids::range, range.toString(), nullptr);
 -         v.setProperty (Ids::type, (int) type, nullptr);
 - 
 -         if (associatedDiagnostic != nullptr)
 -             v.addChild (associatedDiagnostic->toValueTree(), 0, nullptr);
 - 
 -         return v;
 -     }
 - 
 -     static DiagnosticMessage fromValueTree (const ValueTree& v)
 -     {
 -         DiagnosticMessage d;
 -         d.message = v[Ids::text];
 -         d.mainFile = v[Ids::file];
 -         d.range = SourceCodeRange (v [Ids::range]);
 -         d.type = (Type) static_cast<int> (v[Ids::type]);
 - 
 -         auto associated = v.getChild (0);
 -         if (associated.isValid())
 -             d.associatedDiagnostic = new DiagnosticMessage (fromValueTree (associated));
 - 
 -         return d;
 -     }
 - 
 -     bool operator== (const DiagnosticMessage& other) const noexcept
 -     {
 -         return range == other.range
 -                 && message == other.message
 -                 && mainFile == other.mainFile;
 -     }
 - 
 -     bool operator!= (const DiagnosticMessage& other) const noexcept    { return ! operator== (other); }
 - };
 - 
 - //==============================================================================
 - struct DiagnosticReceiver
 - {
 -     virtual ~DiagnosticReceiver() {}
 -     virtual void handleDiagnostic (const DiagnosticMessage&) = 0;
 - };
 - 
 - //==============================================================================
 - struct DiagnosticList
 - {
 -     // after some research, it seems that notes never come on their own
 -     // i.e. they always have a warning / error preceding them
 -     // so we can use this to keep notes and their associated notes together
 -     // by keeping track of the last message
 -     DiagnosticMessage lastMessage;
 - 
 -     ValueTree list { MessageTypes::DIAGNOSTIC_LIST };
 - 
 -     void clear()
 -     {
 -         list = ValueTree { MessageTypes::DIAGNOSTIC_LIST };
 -         lastMessage = DiagnosticMessage();
 -     }
 - 
 -     void add (DiagnosticMessage m)
 -     {
 -         if (m.isNote())
 -         {
 -             if (lastMessage.message.isEmpty())
 -                 return; // seems to happen sometimes, but with seemingly duplicated messages (?)
 - 
 -             m.associatedDiagnostic = new DiagnosticMessage (lastMessage);
 -         }
 -         else
 -         {
 -             lastMessage = m;
 -         }
 - 
 -         list.addChild (m.toValueTree(), -1, nullptr);
 -     }
 - 
 -     void add (const DiagnosticList& l)
 -     {
 -         jassert (l.list != list);
 - 
 -         for (int i = 0; i < l.list.getNumChildren(); ++i)
 -             list.addChild (l.list.getChild(i).createCopy(), -1, nullptr);
 -     }
 - 
 -     const ValueTree& toValueTree() const noexcept
 -     {
 -         return list;
 -     }
 - 
 -     void loadFromChildOfValueTree (ValueTree& parent)
 -     {
 -         list = parent.getChildWithName (MessageTypes::DIAGNOSTIC_LIST).createCopy();
 -     }
 - };
 
 
  |