/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * 
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is Komodo code.
 * 
 * The Initial Developer of the Original Code is ActiveState Software Inc.
 * Portions created by ActiveState Software Inc are Copyright (C) 2000-2007
 * ActiveState Software Inc. All Rights Reserved.
 * 
 * Contributor(s):
 *   ActiveState Software Inc
 * 
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */

// Komodo's linting backend
//
// Here is how linting basically works: The JavaScript runtime gets a
// handle on the koLintingService and makes requests (koILintRequest)
// to lint given documents. The linting service processes those requests
// asynchronously with appropriate koILinter instances and passes results
// back via 'lint_results' (koILintResults) notifications.
// It is then up to the JavaScript runtime to display those results as it
// sees fit (see koLintDisplayer.py).
//


#include "nsISupports.idl"
#include "koIEncoding.idl"
#include "ISciMoz.idl"
#include "nsIObserverService.idl"
interface koIDocument;
interface koILintRequest;
interface koIPreferenceSet;

[scriptable, uuid(2164884D-492F-11d4-AC24-0090273E6A60)]
interface koILintResult : nsISupports
{
    //XXX should maybe be derived from something in common with FindResult
    //XXX because display and navigation should be similar for both
    attribute long lineStart;   // negative value indicates unknown line
    attribute long lineEnd;     // negative value indicates unknown line
    attribute long columnStart; // negative value indicates unknown column
    attribute long columnEnd;   // negative value indicates unknown column
    
    attribute wstring description;

    //XXX look at perldoc perldiag for good list of possible severities
    const long SEV_INFO = 0;
    const long SEV_WARNING = 1;
    const long SEV_ERROR = 2;
    attribute long severity;

    // Constants used for Scintilla decorators introduced 2007-spring
    // XXX: soft chars are why these decl'ns should be moved elsewhere.
    // They need to be kept together because different custom indicators
    // need different values. 
    const long DECORATOR_ERROR = 15;
    const long DECORATOR_WARNING = 16;
    const long DECORATOR_SOFT_CHAR = 17;
    const long DECORATOR_UDL_FAMILY_TRANSITION = 18;
    const long DECORATOR_TABSTOP_TSZW = 19; // Zero-width
    const long DECORATOR_TABSTOP_TSC = 20;  // Current
    const long DECORATOR_TABSTOP_TSCZW = 21;  // Current, zero-width
    const long DECORATOR_TABSTOP_TS1 = 22; // Most snippets need at most 2
    const long DECORATOR_TABSTOP_TS2 = 23;
    const long DECORATOR_TABSTOP_TS3 = 24;
    const long DECORATOR_TABSTOP_TS4 = 25;
    const long DECORATOR_TABSTOP_TS5 = 26;
    const long DECORATOR_TABSTOP_LAST = 26;
    const long DECORATOR_TABSTOP_BITMASK = 0x07f80000;
    const long DECORATOR_FIND_HIGHLIGHT = 27;
    const long INDICATOR_HYPERLINK = 28;
    const long DECORATOR_TAG_MATCH_HIGHLIGHT = 29; // currently also used for
            // automatic variable highlighting (kd 0277, bug 80095)
  
    // Note: We can go up to 63 indicators, though any indicator above 31 will
    //       not work with the scimoz.indicatorAllOnFor() method.
};

[scriptable, uuid(D990E18E-807F-47f9-8C9D-5D2AC5D9A4CF)]
interface koILintResults : nsISupports {
    void addResult(in koILintResult result);
    koILintResults addResults(in koILintResults results);
    void getResults([array, size_is(count)] out koILintResult results,
                    out unsigned long count);
    // This one _was_ used by the old kombo.js for displaying a tooltip.
    // No longer it seems.
    void getResultsInLineRange(in long start, in long end,
                               [array, size_is(count)] out koILintResult results,
                               out unsigned long count);
    void getResultsAtPosition(in long line, in long column,
                              [array, size_is(count)] out koILintResult results,
                              out unsigned long count);

    // Convenience methods (for status bar UI).
    long getNumResults();
    long getNumWarnings();
    long getNumErrors();
    koILintResult getNextResult(in long line, in long column);
};


[scriptable, uuid(2164884B-492F-11d4-AC24-0090273E6A60)]
interface koILinter : nsISupports
{  
    // Check/lint the given content.
    //
    //  "request" is a the koILintRequest object. Generally the linter only
    //      needs the "content", "cwd" and "encoding" attributes.
    //
    // If there is an error linting then an exception should be raised.
    // How the error is handled is up to the caller but the errno may be
    // used to ensure that subsequent errors of the same errno are suppressed
    // (so the user is not unnecessarily innudated).

    // Most linters will call the lint method.
    // Python code accessing the unwrapped object has three keyword args:
    // koILintResults lint(in koILintRequest request,
    //                     in string[] argv_additions, # for htmltidy
    //                     in dict udlMapping, # eg treat all Ruby code as RHTML
    //                     # next arg lets us wrap or replace std linters
    //                     # for sublanguages.
    //                     in dict {langName => koILinter});
    koILintResults lint(in koILintRequest request);
};


// JS-implemented interface to enable the Python backend to pass results
// back to the UI. (XXX: a nsIObserver-mechanism was being clumsily used
// for this before.)
[scriptable, uuid(4912AE60-7AD4-4B02-9D9D-8CE4199C67A3)]
interface koILintBuffer : nsISupports {
    void reportResults(in koILintRequest request);
};


[scriptable, uuid(0A5B4FFC-737C-4103-992F-CB1BB2504598)]
interface koILintRequest : nsISupports {
    // This first block of attributes should be set when the request is made.
    attribute long rid; // relatively-unique request id
    attribute koIDocument document; // DEPRECATED in Komodo 6.0.0, use `koDoc`
    attribute koIDocument koDoc;
    attribute koIPreferenceSet prefset;
    attribute string uid;        // a unique view id
    // Specifying a null linterType will just result in an encoding check
    // on the document.
    attribute string linterType;
    attribute wstring cwd;
    attribute koILintBuffer lintBuffer;

    // The following attributes are for internal use and/or are set while
    // processing the request.
    attribute AString content;
    attribute koIEncoding encoding;
    attribute koILinter linter;
    attribute koILintResults results;
    attribute string errorString;
    attribute boolean alwaysLint;

    wstring describe(); // Return a desc of this request. For debugging.
};


[scriptable, uuid(2AC66B1E-77CD-493D-A8FC-8188B7881BC4)]
interface koILintService : nsISupports {
    // Request a lint.
    // If there is an error an exception is raised and an error is set on
    // koILintRequest:errorString.
    void addRequest(in koILintRequest request);
    
    // Cancel all pending lint requests for the given view.
    //
    //  "uid" is meant to uniquely identify a view (XXX crappy name))
    //
    // Note that if there is a request currently being processed (whether
    // for this "uid" or not, it is NOT cancelled).
    void cancelPendingRequests(in string uid);

    wstring getLinter_CID_ForLanguage(in wstring languageName);
    koILinter getLinterForLanguage(in wstring languageName);
};


