Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: ae49954f4650e9181854c1580ba2f26f69215cce (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*******************************************************************************
 * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Markus Schorn - initial API and implementation
 *     Sergey Prigogin (Google)
 *******************************************************************************/ 
package org.eclipse.cdt.internal.core.parser.scanner;

import java.util.ArrayList;
import java.util.Collection;

import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;

/**
 * A location context representing a file.
 * @since 5.0
 */
class LocationCtxFile extends LocationCtxContainer {
	private final String fFilename;
	private final ASTInclusionStatement fASTInclude;
	private final boolean fIsSource;
	private boolean fInsideIncludeExportBlock;
	private int fOffsetOfIncludeExport = -1;

	public LocationCtxFile(LocationCtxContainer parent, String filename, AbstractCharArray source,
			int parentOffset, int parentEndOffset, int sequenceNumber,
			ASTInclusionStatement inclusionStatement, boolean isSource) {
		super(parent, source, parentOffset, parentEndOffset, sequenceNumber);
		fFilename= filename;
		fASTInclude= inclusionStatement;
		fIsSource= isSource;
	}
	
	@Override
	public final void addChildSequenceLength(int childLength) {
		super.addChildSequenceLength(childLength);
	}

	@Override
	public final String getFilePath() {
		return fFilename;
	}

	@Override
	public ASTFileLocation findMappedFileLocation(int sequenceNumber, int length) {
		// Try to delegate to a child.
		final int testEnd= length > 1 ? sequenceNumber + length - 1 : sequenceNumber;
		final int sequenceEnd= sequenceNumber + length;
		final LocationCtx child1= findChildLessOrEqualThan(sequenceNumber, false);
		final LocationCtx child2= testEnd == sequenceNumber ?
				child1 : findChildLessOrEqualThan(testEnd, false);
	
		if (child1 == child2 && child1 != null &&
				child1.fSequenceNumber + child1.getSequenceLength() > testEnd) {
			return child1.findMappedFileLocation(sequenceNumber, length);
		}
		
		// Handle here.
		int startOffset;
		int endOffset;
		
		if (child1 == null) {
			startOffset= sequenceNumber - fSequenceNumber;
		} else {
			int childSequenceEnd= child1.fSequenceNumber + child1.getSequenceLength();
			if (sequenceNumber < childSequenceEnd) {
				startOffset= child1.fOffsetInParent;
			} else {	// Start beyond child1
				startOffset= child1.fEndOffsetInParent + sequenceNumber - childSequenceEnd;
			}
		}
		if (child2 == null) {
			endOffset= sequenceEnd - fSequenceNumber;
		} else {
			int childSequenceEnd= child2.fSequenceNumber + child2.getSequenceLength();
			if (childSequenceEnd < sequenceEnd) { // Beyond child2
				endOffset= child2.fEndOffsetInParent + sequenceEnd - childSequenceEnd;
			} else {
				endOffset= child2.fEndOffsetInParent;
			}
		}
		return new ASTFileLocation(this, startOffset, endOffset - startOffset);
	}
	
	@Override
	public ASTFileLocation createMappedFileLocation(int offset, int length) {
		return new ASTFileLocation(this, offset, length);
	}

	@Override
	public ASTInclusionStatement getInclusionStatement() {
		return fASTInclude;
	}

	@Override
	ASTFileLocation createFileLocation(int start, int length) {
		return new ASTFileLocation(this, start, length);
	}

	public boolean isThisFile(int sequenceNumber) {
		if (sequenceNumber < 0)
			return false;
		LocationCtx child= findChildLessOrEqualThan(sequenceNumber, false);
		if (!(child instanceof LocationCtxFile))
			return true;
		return sequenceNumber >= child.fSequenceNumber + child.getSequenceLength();
	}

	public void collectMacroExpansions(int offset, int length,
			ArrayList<IASTPreprocessorMacroExpansion> list) {
		Collection<LocationCtx> children= getChildren();
		for (LocationCtx ctx : children) {
			// Context must start before the end of the search range.
			if (ctx.fOffsetInParent >= offset+length) {
				break;
			}
			if (ctx instanceof LocationCtxMacroExpansion) {
				// Expansion must end after the search start.
				if (ctx.fEndOffsetInParent > offset) {
					IASTNode macroExpansion =
							((LocationCtxMacroExpansion) ctx).getMacroReference().getParent();
					list.add((IASTPreprocessorMacroExpansion) macroExpansion);
				}
			}
		}
	}
	
	@Override
	public boolean isSourceFile() {
		return fIsSource;
	}
	
	@Override
	public String toString() {
		return fFilename;
	}

	public boolean isInsideIncludeExportBlock() {
		return fInsideIncludeExportBlock;
	}

	public void setInsideIncludeExportBlock(boolean fInsideIncludeExportBlock) {
		this.fInsideIncludeExportBlock = fInsideIncludeExportBlock;
	}

	public int getOffsetOfIncludeExport() {
		return fOffsetOfIncludeExport;
	}

	public void setOffsetOfIncludeExport(int fOffsetOfIncludeExport) {
		this.fOffsetOfIncludeExport = fOffsetOfIncludeExport;
	}
}

Back to the top