summaryrefslogtreecommitdiff
path: root/sources/scala/tools/util/SourceFile.java
blob: 025f7602ad1fef0dae09e8d2f3ad02399e07d209 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scala.tools.util;


/** This class represents a single source file. */
public class SourceFile {

    //########################################################################
    // Public Constants

    /** Constants used for source parsing */
    public static final char LF = 0x0A;
    public static final char FF = 0x0C;
    public static final char CR = 0x0D;
    public static final char SU = 0x1A;

    //########################################################################
    // Private Fields

    /** The underlying file */
    private final AbstractFile file;

    /** The content of this source file */
    private final char[] content;

    /** The position of the last line returned by getLine */
    private int lineNumber = 0;
    private int lineStart  = 0;
    private int lineLength = 0;
    private int nextIndex  = 0;

    //########################################################################
    // Public Constructors

    /** Initializes this instance with given name and content. */
    public SourceFile(String sourcename, char[] content) {
        this(new CharArrayFile(sourcename, content), content);
    }

    /** Initializes this instance with given file and content. */
    public SourceFile(AbstractFile file, char[] content) {
        this.file = file;
        this.content = normalize(content);
    }

    //########################################################################
    // Public Methods

    /** Returns the underlying file. */
    public AbstractFile getFile() {
        return file;
    }

    /** Returns the content of this source file. */
    public char[] getContent() {
        return content;
    }

    /**
     * Returns an instance of Position representing the given line and
     * column of this source file.
     */
    public Position getPosition(int line, int column) {
        return new Position(this, line, column);
    }

    /** Returns the specified line. */
    public String getLine(int line) {
        int index = lineNumber <= line ? nextIndex : (lineNumber = 0);
        for (; index < content.length && lineNumber < line; lineNumber++) {
            lineStart = index;
            for (; index < content.length; index++) {
                if (content[index] == CR) break;
                if (content[index] == LF) break;
                if (content[index] == FF) break;
            }
            lineLength = index - lineStart;
            if (index < content.length)
                index++;
            if (index < content.length)
                if (content[index - 1] == CR && content[index] == LF) index++;
        }
        nextIndex = index;
        return new String(content, lineStart, lineLength);
    }

    /** Returns the path of the underlying file. */
    public String toString() {
        return file.toString();
    }

    public int hashCode() {
	return file.hashCode();
    }

    public boolean equals(Object that) {
	return that instanceof SourceFile &&
	    file.equals(((SourceFile) that).file);
    }

    //########################################################################
    // Private Functions

    /** Ensures that the last char of the array is SU. */
    private static char[] normalize(char[] input) {
        if (input.length > 0 && input[input.length - 1] == SU)
                return input;
        char[] content = new char[input.length + 1];
        System.arraycopy(input, 0, content, 0, input.length);
        content[input.length] = SU;
        return content;
    }

    //########################################################################
}