This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 255176
Collapse All | Expand All

(-)a/cnd.api.model/src/org/netbeans/modules/cnd/api/model/CsmFile.java (+6 lines)
Lines 51-56 Link Here
51
 * @author Vladimir Kvashin
51
 * @author Vladimir Kvashin
52
 */
52
 */
53
public interface CsmFile extends CsmNamedElement, CsmScope, CsmValidable {
53
public interface CsmFile extends CsmNamedElement, CsmScope, CsmValidable {
54
    
55
    /** Adds the property to this file */
56
    void putProperty(Object key, Object value);
57
    
58
    /** Gets the property associated with this file */
59
    Object getProperty(Object key);
54
60
55
    /** Gets this file normalized absolute path */
61
    /** Gets this file normalized absolute path */
56
    CharSequence getAbsolutePath();
62
    CharSequence getAbsolutePath();
(-)a/cnd.completion/src/org/netbeans/modules/cnd/completion/cplusplus/CsmCompletionUtils.java (-1 / +4 lines)
Lines 78-84 Link Here
78
     * @see NbEditorDocument#MIME_TYPE_PROP
78
     * @see NbEditorDocument#MIME_TYPE_PROP
79
     */
79
     */
80
    public  static String getMimeType(Document doc) {
80
    public  static String getMimeType(Document doc) {
81
        return DocumentUtilities.getMimeType(doc);
81
        return doc != null ? DocumentUtilities.getMimeType(doc) : null;
82
    }
82
    }
83
83
84
    /**
84
    /**
Lines 116-121 Link Here
116
    }
116
    }
117
117
118
    public static boolean isNaturalSort(String mimeType) {
118
    public static boolean isNaturalSort(String mimeType) {
119
        if (mimeType == null || mimeType.length() == 0) {
120
            return false;
121
        }
119
        Preferences prefs = MimeLookup.getLookup(mimeType).lookup(Preferences.class);
122
        Preferences prefs = MimeLookup.getLookup(mimeType).lookup(Preferences.class);
120
        return prefs.getBoolean(SimpleValueNames.COMPLETION_NATURAL_SORT, false);
123
        return prefs.getBoolean(SimpleValueNames.COMPLETION_NATURAL_SORT, false);
121
    }
124
    }
(-)a/cnd.completion/src/org/netbeans/modules/cnd/completion/cplusplus/ext/CompletionSupport.java (-1 / +25 lines)
Lines 129-144 Link Here
129
public final class CompletionSupport implements DocumentListener {
129
public final class CompletionSupport implements DocumentListener {
130
130
131
    private final Reference<Document> docRef;
131
    private final Reference<Document> docRef;
132
    private final Reference<CsmFile> fileRef;
132
    // not for external instantiation
133
    // not for external instantiation
133
134
135
    public CompletionSupport(CsmFile file) {
136
        docRef = new WeakReference<Document>(null);
137
        fileRef = new WeakReference<CsmFile>(file);
138
    }
139
134
    private CompletionSupport(Document doc) {
140
    private CompletionSupport(Document doc) {
135
        docRef = new WeakReference<Document>(doc);
141
        docRef = new WeakReference<Document>(doc);
142
        fileRef = new WeakReference<CsmFile>(null);
136
        doc.addDocumentListener(this);
143
        doc.addDocumentListener(this);
137
    }
144
    }
138
145
139
    public static CompletionSupport get(JTextComponent component) {
146
    public static CompletionSupport get(JTextComponent component) {
140
        return get(component.getDocument());
147
        return get(component.getDocument());
141
    }
148
    }
149
    
150
    public static CompletionSupport get(final Document doc, final CsmFile file) {
151
        return (doc != null) ? get(doc) : get(file);
152
    }
142
153
143
    public static CompletionSupport get(final Document doc) {
154
    public static CompletionSupport get(final Document doc) {
144
        CompletionSupport support = (CompletionSupport) doc.getProperty(CompletionSupport.class);
155
        CompletionSupport support = (CompletionSupport) doc.getProperty(CompletionSupport.class);
Lines 158-167 Link Here
158
        }
169
        }
159
        return support;
170
        return support;
160
    }
171
    }
172
    
173
    public static CompletionSupport get(final CsmFile file) {
174
        // no cache for now
175
        return new CompletionSupport(file);
176
    }
161
177
162
    public final Document getDocument() {
178
    public final Document getDocument() {
163
        return this.docRef.get();
179
        return this.docRef.get();
164
    }
180
    }
181
    
182
    public final CsmFile getFile() {
183
        return this.fileRef.get();
184
    }
165
185
166
    public static boolean isPreprocCompletionEnabled(Document doc, int offset) {
186
    public static boolean isPreprocCompletionEnabled(Document doc, int offset) {
167
        return isIncludeCompletionEnabled(doc, offset) || isPreprocessorDirectiveCompletionEnabled(doc, offset);
187
        return isIncludeCompletionEnabled(doc, offset) || isPreprocessorDirectiveCompletionEnabled(doc, offset);
Lines 251-257 Link Here
251
271
252
    public int doc2context(int docPos) {
272
    public int doc2context(int docPos) {
253
        int offset = this.contextOffset == NOT_INITIALIZED ? docPos : this.contextOffset;
273
        int offset = this.contextOffset == NOT_INITIALIZED ? docPos : this.contextOffset;
254
        offset = CsmMacroExpansion.getOffsetInOriginalText(getDocument(), offset);
274
        if (getDocument() != null) {
275
            offset = CsmMacroExpansion.getOffsetInOriginalText(getDocument(), offset);
276
        } else {
277
            offset = CsmMacroExpansion.getOffsetInOriginalText(getFile(), offset);
278
        }
255
        return offset;
279
        return offset;
256
    }
280
    }
257
281
(-)a/cnd.completion/src/org/netbeans/modules/cnd/completion/cplusplus/ext/CsmCompletionQuery.java (-28 / +44 lines)
Lines 354-367 Link Here
354
        if (enterThreadLocalAntiloop(AntiloopClient.query_type, expression)) {
354
        if (enterThreadLocalAntiloop(AntiloopClient.query_type, expression)) {
355
            try {
355
            try {
356
                CsmCacheManager.enter();
356
                CsmCacheManager.enter();
357
                
358
                // Note that baseDocument can be null
357
                baseDocument = (BaseDocument) CsmUtilities.getDocument(expression.getContainingFile());
359
                baseDocument = (BaseDocument) CsmUtilities.getDocument(expression.getContainingFile());
358
                if (baseDocument == null) {
360
                assert getBaseDocument() != null || getCsmFile() != null : "Either document or CsmFile must be provided!"; // NOI18N
359
                    CloneableEditorSupport support = CsmUtilities.findCloneableEditorSupport(expression.getContainingFile());
360
                    if (support == null) {
361
                        return false;
362
                    }
363
                    baseDocument = (BaseDocument) support.openDocument();
364
                }
365
361
366
                final int startOffset = expression.getStartOffset();
362
                final int startOffset = expression.getStartOffset();
367
                final int endOffset = expression.getEndOffset();
363
                final int endOffset = expression.getEndOffset();
Lines 370-377 Link Here
370
//                    return false;
366
//                    return false;
371
//                }
367
//                }
372
368
373
                long docVersion = DocumentUtilities.getDocumentVersion(baseDocument);
374
375
        //        TokenProcessorCache property = (TokenProcessorCache) baseDocument.getProperty(TOKEN_PROCESSOR_CACHE_KEY);
369
        //        TokenProcessorCache property = (TokenProcessorCache) baseDocument.getProperty(TOKEN_PROCESSOR_CACHE_KEY);
376
        //        CsmCompletionTokenProcessor tp = null;
370
        //        CsmCompletionTokenProcessor tp = null;
377
        //        if (property != null) {
371
        //        if (property != null) {
Lines 385-398 Link Here
385
                }
379
                }
386
380
387
                CsmCompletionTokenProcessor tp;
381
                CsmCompletionTokenProcessor tp;
388
389
                CsmScope passedScope = null;
382
                CsmScope passedScope = null;
390
383
391
                if (CsmKindUtilities.isExpression(expression)) {
384
                if (CsmKindUtilities.isExpression(expression)) {
392
                    passedScope = ((CsmExpression) expression).getScope();
385
                    passedScope = ((CsmExpression) expression).getScope();
393
                    tp = processTokensInExpression((CsmExpression) expression, task.isFindTypeTask());
386
                    tp = processTokensInExpression((CsmExpression) expression, task.isFindTypeTask());
394
                } else {
387
                } else {
395
                    tp = processTokensInFile(csmFile, startOffset, endOffset, baseDocument, docVersion);
388
                    tp = processTokensInFile(csmFile, startOffset, endOffset, baseDocument);
396
                }
389
                }
397
390
398
                if (!checkErrorTokenState(tp)) {
391
                if (!checkErrorTokenState(tp)) {
Lines 429-436 Link Here
429
                } else if (TRACE_COMPLETION) {
422
                } else if (TRACE_COMPLETION) {
430
                    System.err.println("Error expression " + tp.getResultExp());
423
                    System.err.println("Error expression " + tp.getResultExp());
431
                }
424
                }
432
            } catch (IOException ex) {
433
                ex.printStackTrace(System.err);
434
            } finally {
425
            } finally {
435
                exitThreadLocalAntiloop(AntiloopClient.query_type, expression);
426
                exitThreadLocalAntiloop(AntiloopClient.query_type, expression);
436
                CsmCacheManager.leave();
427
                CsmCacheManager.leave();
Lines 561-567 Link Here
561
            if (tp == null) {
552
            if (tp == null) {
562
                // find last separator position
553
                // find last separator position
563
                final int lastSepOffset = sup.getLastCommandSeparator(csmFile, offset, getFileReferencesContext());
554
                final int lastSepOffset = sup.getLastCommandSeparator(csmFile, offset, getFileReferencesContext());
564
                tp = processTokensInFile(csmFile, lastSepOffset, offset, doc, docVersion);
555
                tp = processTokensInFile(csmFile, lastSepOffset, offset, doc);
565
                baseDocument.putProperty(TOKEN_PROCESSOR_CACHE_KEY, new TokenProcessorCache(offset, docVersion, tp));
556
                baseDocument.putProperty(TOKEN_PROCESSOR_CACHE_KEY, new TokenProcessorCache(offset, docVersion, tp));
566
            } else {
557
            } else {
567
                // hit
558
                // hit
Lines 719-725 Link Here
719
        return errState;
710
        return errState;
720
    }
711
    }
721
712
722
    private CsmCompletionTokenProcessor processTokensInFile(CsmFile csmFile, final int startOffset, final int endOffset, final BaseDocument doc, final long docVersion) {
713
    private CsmCompletionTokenProcessor processTokensInFile(CsmFile csmFile, final int startOffset, final int endOffset, final BaseDocument doc) {
723
        CsmCompletionTokenProcessor tp = new CsmCompletionTokenProcessor(endOffset, startOffset);
714
        CsmCompletionTokenProcessor tp = new CsmCompletionTokenProcessor(endOffset, startOffset);
724
        final CndTokenProcessor<Token<TokenId>> etp = CsmExpandedTokenProcessor.create(csmFile, doc, tp, endOffset);
715
        final CndTokenProcessor<Token<TokenId>> etp = CsmExpandedTokenProcessor.create(csmFile, doc, tp, endOffset);
725
        if(etp instanceof CsmExpandedTokenProcessor) {
716
        if(etp instanceof CsmExpandedTokenProcessor) {
Lines 727-738 Link Here
727
        }
718
        }
728
        tp.enableLambdaSupport(areLambdasEnabled(csmFile));
719
        tp.enableLambdaSupport(areLambdasEnabled(csmFile));
729
        tp.enableTemplateSupport(areTemplatesEnabled(csmFile));
720
        tp.enableTemplateSupport(areTemplatesEnabled(csmFile));
730
        doc.render(new Runnable() {
721
        if (doc != null) {
731
            @Override
722
            doc.render(new Runnable() {
732
            public void run() {
723
                @Override
733
                CndTokenUtilities.processTokens(etp, doc, startOffset, endOffset);
724
                public void run() {
725
                    CndTokenUtilities.processTokens(etp, doc, startOffset, endOffset);
726
                }
727
            });
728
        } else {
729
            TokenSequence<TokenId> cppTokenSequence = CsmFileInfoQuery.getDefault().getCppTokenSequence(csmFile, startOffset, false, endOffset < startOffset);
730
            if (cppTokenSequence != null) {
731
                CndTokenUtilities.processTokens(etp, cppTokenSequence, startOffset, endOffset);
734
            }
732
            }
735
        });
733
        }
736
        return tp;
734
        return tp;
737
    }
735
    }
738
736
Lines 748-759 Link Here
748
        int exprEndOffset = exprStartOffset + expressionText.length();
746
        int exprEndOffset = exprStartOffset + expressionText.length();
749
747
750
        final CsmCompletionTokenProcessor tp = new CsmCompletionTokenProcessor(exprEndOffset, exprStartOffset);
748
        final CsmCompletionTokenProcessor tp = new CsmCompletionTokenProcessor(exprEndOffset, exprStartOffset);
751
        TokenHierarchy<String> hi = TokenHierarchy.create(
749
        
752
            expressionText,
750
        final Language<CppTokenId> language = getBaseDocument() != null ? 
753
            false,
751
            CndLexerUtilities.getLanguage(getBaseDocument()) 
754
            CndLexerUtilities.getLanguage(getBaseDocument()),
752
            : CsmFileInfoQuery.getDefault().getFileLexerLanguage(getCsmFile());
753
        
754
        final InputAttributes attributes = getBaseDocument() != null ? 
755
            (InputAttributes) getBaseDocument().getProperty(InputAttributes.class)
756
            : null;
757
        
758
        TokenHierarchy<String> hi = TokenHierarchy.create(expressionText,
759
            false, 
760
            language,
755
            null,
761
            null,
756
            (InputAttributes) getBaseDocument().getProperty(InputAttributes.class)
762
            attributes
757
        );
763
        );
758
        List<TokenSequence<?>> tsList = hi.embeddedTokenSequences(exprEndOffset - exprStartOffset, true);
764
        List<TokenSequence<?>> tsList = hi.embeddedTokenSequences(exprEndOffset - exprStartOffset, true);
759
        // Go from inner to outer TSes
765
        // Go from inner to outer TSes
Lines 777-782 Link Here
777
783
778
        return tp;
784
        return tp;
779
    }
785
    }
786
    
787
    private CsmCompletionExpression getResultExpression(CsmCompletionTokenProcessor tp, boolean processedAsExpression, boolean keepWholeAst) {
788
        if (processedAsExpression && keepWholeAst) {
789
            // See implementation of processTokensInExpression
790
            CsmCompletionExpression resultExp = tp.getResultExp();
791
            if (resultExp != null && resultExp.getParameterCount() == 1 && resultExp.getExpID() == CsmCompletionExpression.PARENTHESIS) {
792
                return resultExp.getParameter(0);
793
            }
794
        }
795
        return tp.getResultExp();
796
    }
780
797
781
    abstract protected boolean isProjectBeeingParsed(boolean openingSource);
798
    abstract protected boolean isProjectBeeingParsed(boolean openingSource);
782
799
Lines 812-818 Link Here
812
                    );
829
                    );
813
                }
830
                }
814
            }
831
            }
815
            CompletionSupport sup = CompletionSupport.get(doc);
832
            CompletionSupport sup = CompletionSupport.get(doc, getCsmFile());
816
            CsmOffsetableDeclaration context = sup.getDefinition(contextScope);
833
            CsmOffsetableDeclaration context = sup.getDefinition(contextScope);
817
            if (context == null) {
834
            if (context == null) {
818
                context = sup.getDefinition(getCsmFile(), offset, getFileReferencesContext());
835
                context = sup.getDefinition(getCsmFile(), offset, getFileReferencesContext());
Lines 1457-1464 Link Here
1457
                if (CsmKindUtilities.isExpression(expression)) {
1474
                if (CsmKindUtilities.isExpression(expression)) {
1458
                    tp = processTokensInExpression((CsmExpression) expression, true);
1475
                    tp = processTokensInExpression((CsmExpression) expression, true);
1459
                } else {
1476
                } else {
1460
                    long docVersion = DocumentUtilities.getDocumentVersion(getBaseDocument());
1477
                    tp = processTokensInFile(expression.getContainingFile(), expression.getStartOffset(), expression.getEndOffset(), getBaseDocument());
1461
                    tp = processTokensInFile(expression.getContainingFile(), expression.getStartOffset(), expression.getEndOffset(), getBaseDocument(), docVersion);
1462
                }
1478
                }
1463
1479
1464
                if (!checkErrorTokenState(tp)) {
1480
                if (!checkErrorTokenState(tp)) {
(-)a/cnd.lexer/src/org/netbeans/cnd/api/lexer/CndLexerUtilities.java (+33 lines)
Lines 147-152 Link Here
147
        }
147
        }
148
        return null;
148
        return null;
149
    }
149
    }
150
    
151
    /**
152
     * returns C/C++/Preprocessor tokens sequence for text
153
     * @param text cpp source text
154
     * @param offset offset
155
     * @param language language
156
     * @param lexPP if <code>true</code> and offset is in preprocessor directive then return tokens sequence of this
157
     * directive. If <code>false</code> and offset is in preprocessor directive do not dive into embedding
158
     * @param backwardBias @see TokenHierarchy.embeddedTokenSequences
159
     * If <code>true</code> the backward lying token will
160
     *   be used in case that the <code>offset</code> specifies position between
161
     *   two tokens. If <code>false</code> the forward lying token will be used.     * 
162
     * @return token sequence positioned on token with offset (no need to call moveNext()/movePrevious() before token())
163
     */
164
    public static <Input extends CharSequence> TokenSequence<TokenId> getCppTokenSequence(final Input text, final int offset, Language<?> language,
165
            boolean lexPP, boolean backwardBias) {
166
        if (text == null) {
167
            return null;
168
        }
169
        TokenHierarchy<Input> hi = TokenHierarchy.create(text, language);
170
        List<TokenSequence<?>> tsList = hi.embeddedTokenSequences(offset, backwardBias);
171
        // Go from inner to outer TSes
172
        for (int i = tsList.size() - 1; i >= 0; i--) {
173
            TokenSequence<?> ts = tsList.get(i);
174
            final Language<?> lang = ts.languagePath().innerLanguage();
175
            if (isCppLanguage(lang, lexPP)) {
176
                @SuppressWarnings("unchecked")
177
                TokenSequence<TokenId> cppInnerTS = (TokenSequence<TokenId>) ts;
178
                return cppInnerTS;
179
            }
180
        }
181
        return null;
182
    }
150
183
151
    public static TokenSequence<TokenId> getCppTokenSequenceWithoutEmbeddings(final Document doc, final int offset) {
184
    public static TokenSequence<TokenId> getCppTokenSequenceWithoutEmbeddings(final Document doc, final int offset) {
152
        if (doc == null) {
185
        if (doc == null) {
(-)a/cnd.model.services/src/org/netbeans/modules/cnd/api/model/services/CsmFileInfoQuery.java (+33 lines)
Lines 47-52 Link Here
47
import java.util.Collection;
47
import java.util.Collection;
48
import java.util.Collections;
48
import java.util.Collections;
49
import java.util.List;
49
import java.util.List;
50
import org.netbeans.api.lexer.TokenId;
51
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.modules.cnd.api.model.CsmErrorDirective;
52
import org.netbeans.modules.cnd.api.model.CsmErrorDirective;
51
import org.netbeans.modules.cnd.api.model.CsmFile;
53
import org.netbeans.modules.cnd.api.model.CsmFile;
52
import org.netbeans.modules.cnd.api.model.CsmInclude;
54
import org.netbeans.modules.cnd.api.model.CsmInclude;
Lines 183-188 Link Here
183
    
185
    
184
    /**
186
    /**
185
     * 
187
     * 
188
     * @param file
189
     * @return language for lexer
190
     */
191
    public abstract org.netbeans.api.lexer.Language getFileLexerLanguage(CsmFile file);
192
    
193
    /**
194
     * returns C/C++/Preprocessor tokens sequence for text
195
     * @param file cpp source file
196
     * @param offset offset
197
     * @param lexPP if <code>true</code> and offset is in preprocessor directive then return tokens sequence of this
198
     * directive. If <code>false</code> and offset is in preprocessor directive do not dive into embedding
199
     * @param backwardBias @see TokenHierarchy.embeddedTokenSequences
200
     * If <code>true</code> the backward lying token will
201
     *   be used in case that the <code>offset</code> specifies position between
202
     *   two tokens. If <code>false</code> the forward lying token will be used.     * 
203
     * @return token sequence positioned on token with offset (no need to call moveNext()/movePrevious() before token())
204
     */
205
    public abstract TokenSequence<TokenId> getCppTokenSequence(final CsmFile file, final int offset, boolean lexPP, boolean backwardBias);
206
    
207
    /**
208
     * 
186
     * @param langFlavor - pair of language and flavor
209
     * @param langFlavor - pair of language and flavor
187
     * @return pair of language and flavor in terms of APT
210
     * @return pair of language and flavor in terms of APT
188
     */
211
     */
Lines 320-325 Link Here
320
        }
343
        }
321
344
322
        @Override
345
        @Override
346
        public org.netbeans.api.lexer.Language getFileLexerLanguage(CsmFile file) {
347
            return null;
348
        }
349
350
        @Override
351
        public TokenSequence<TokenId> getCppTokenSequence(CsmFile file, int offset, boolean lexPP, boolean backwardBias) {
352
            return null;
353
        }
354
355
        @Override
323
        public Pair<String, String> getAPTLanguageFlavor(Pair<Language, LanguageFlavor> langFlavor) {
356
        public Pair<String, String> getAPTLanguageFlavor(Pair<Language, LanguageFlavor> langFlavor) {
324
            return null;
357
            return null;
325
        }
358
        }
(-)a/cnd.model.services/src/org/netbeans/modules/cnd/api/model/services/CsmMacroExpansion.java (+21 lines)
Lines 206-211 Link Here
206
    public static int getOffsetInOriginalText(Document expandedDoc, int expandedOffset) {
206
    public static int getOffsetInOriginalText(Document expandedDoc, int expandedOffset) {
207
        return getMacroExpansionDocProvider().getOffsetInOriginalText(expandedDoc, expandedOffset);
207
        return getMacroExpansionDocProvider().getOffsetInOriginalText(expandedDoc, expandedOffset);
208
    }
208
    }
209
    
210
    /**
211
     * Transforms offset in expanded text to original offset.
212
     *
213
     * @param expandedFile - file
214
     * @param expandedOffset - offset in expanded text
215
     * @return original offset
216
     */
217
    public static int getOffsetInOriginalText(CsmFile expandedFile, int expandedOffset) {
218
        return getMacroExpansionDocProvider().getOffsetInOriginalText(expandedFile, expandedOffset);
219
    }
209
220
210
    /**
221
    /**
211
     * Returns offset of the next macro expansion.
222
     * Returns offset of the next macro expansion.
Lines 291-301 Link Here
291
        }
302
        }
292
303
293
        @Override
304
        @Override
305
        public int getOffsetInExpandedText(CsmFile expandedFile, int originalOffset) {
306
            return originalOffset;
307
        }
308
309
        @Override
294
        public int getOffsetInOriginalText(Document expandedDoc, int expandedOffset) {
310
        public int getOffsetInOriginalText(Document expandedDoc, int expandedOffset) {
295
            return expandedOffset;
311
            return expandedOffset;
296
        }
312
        }
297
313
298
        @Override
314
        @Override
315
        public int getOffsetInOriginalText(CsmFile expandedFile, int expandedOffset) {
316
            return expandedOffset;
317
        }
318
319
        @Override
299
        public int getNextMacroExpansionStartOffset(Document expandedDoc, int expandedOffset) {
320
        public int getNextMacroExpansionStartOffset(Document expandedDoc, int expandedOffset) {
300
            return expandedOffset;
321
            return expandedOffset;
301
        }
322
        }
(-)a/cnd.model.services/src/org/netbeans/modules/cnd/spi/model/services/CsmMacroExpansionDocProvider.java (+18 lines)
Lines 126-131 Link Here
126
     * @return offset in expanded text
126
     * @return offset in expanded text
127
     */
127
     */
128
    public int getOffsetInExpandedText(Document expandedDoc, int originalOffset);
128
    public int getOffsetInExpandedText(Document expandedDoc, int originalOffset);
129
    
130
    /**
131
     * Transforms original offset to offset in expanded text.
132
     *
133
     * @param expandedFile - file
134
     * @param originalOffset - original offset
135
     * @return offset in expanded text
136
     */
137
    public int getOffsetInExpandedText(CsmFile expandedFile, int originalOffset);
129
138
130
    /**
139
    /**
131
     * Transforms offset in expanded text to original offset.
140
     * Transforms offset in expanded text to original offset.
Lines 135-140 Link Here
135
     * @return original offset
144
     * @return original offset
136
     */
145
     */
137
    public int getOffsetInOriginalText(Document expandedDoc, int expandedOffset);
146
    public int getOffsetInOriginalText(Document expandedDoc, int expandedOffset);
147
    
148
    /**
149
     * Transforms offset in expanded text to original offset.
150
     *
151
     * @param expandedFile - file
152
     * @param expandedOffset - offset in expanded text
153
     * @return original offset
154
     */
155
    public int getOffsetInOriginalText(CsmFile expandedFile, int expandedOffset);
138
156
139
    /**
157
    /**
140
     * Returns offset of the next macro expansion.
158
     * Returns offset of the next macro expansion.
(-)a/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/csm/core/FileImpl.java (+13 lines)
Lines 53-58 Link Here
53
import java.util.Collection;
53
import java.util.Collection;
54
import java.util.Collections;
54
import java.util.Collections;
55
import java.util.Comparator;
55
import java.util.Comparator;
56
import java.util.HashMap;
56
import java.util.Iterator;
57
import java.util.Iterator;
57
import java.util.List;
58
import java.util.List;
58
import java.util.Map;
59
import java.util.Map;
Lines 220-225 Link Here
220
    private static volatile AtomicLong parseCount = new AtomicLong(1);
221
    private static volatile AtomicLong parseCount = new AtomicLong(1);
221
222
222
    private Collection<ParserError> parsingErrors;
223
    private Collection<ParserError> parsingErrors;
224
    
225
    private final Map<Object, Object> properties = Collections.synchronizedMap(new HashMap<>());
223
226
224
    public static void incParseCount() {
227
    public static void incParseCount() {
225
        parseCount.incrementAndGet();
228
        parseCount.incrementAndGet();
Lines 1804-1809 Link Here
1804
        checkNotInParsingThreadImpl();
1807
        checkNotInParsingThreadImpl();
1805
        return currentFileContent.getScopeElements();
1808
        return currentFileContent.getScopeElements();
1806
    }
1809
    }
1810
    
1811
    @Override
1812
    public Object getProperty(Object key) {
1813
        return properties.get(key);
1814
    }
1815
1816
    @Override
1817
    public void putProperty(Object key, Object value) {
1818
        properties.put(key, value);
1819
    }
1807
1820
1808
    public void setFileGuard(int guardStart, int guardEnd) {
1821
    public void setFileGuard(int guardStart, int guardEnd) {
1809
        this.guardStart = guardStart;
1822
        this.guardStart = guardStart;
(-)a/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/csm/core/FileSnapshot.java (+10 lines)
Lines 87-92 Link Here
87
    }
87
    }
88
88
89
    @Override
89
    @Override
90
    public Object getProperty(Object key) {
91
        return delegate.getProperty(key);
92
    }
93
94
    @Override
95
    public void putProperty(Object key, Object value) {
96
        delegate.putProperty(key, value);
97
    }
98
99
    @Override
90
    public CharSequence getAbsolutePath() {
100
    public CharSequence getAbsolutePath() {
91
        return absPath;
101
        return absPath;
92
    }
102
    }
(-)a/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/csm/core/Unresolved.java (+10 lines)
Lines 286-291 Link Here
286
        public void dispose() {
286
        public void dispose() {
287
            UIDUtilities.disposeUnresolved(uid);
287
            UIDUtilities.disposeUnresolved(uid);
288
        }
288
        }
289
290
        @Override
291
        public Object getProperty(Object key) {
292
            return null;
293
        }
294
295
        @Override
296
        public void putProperty(Object key, Object value) {
297
            // do nothing
298
        }
289
    };
299
    };
290
300
291
    // only one of projectRef/projectUID must be used (based on USE_UID_TO_CONTAINER)
301
    // only one of projectRef/projectUID must be used (based on USE_UID_TO_CONTAINER)
(-)a/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/impl/services/FileInfoQueryImpl.java (+117 lines)
Lines 37-50 Link Here
37
import java.util.Collections;
37
import java.util.Collections;
38
import java.util.Iterator;
38
import java.util.Iterator;
39
import java.util.List;
39
import java.util.List;
40
import java.util.Objects;
41
import java.util.concurrent.Callable;
40
import java.util.concurrent.ConcurrentHashMap;
42
import java.util.concurrent.ConcurrentHashMap;
41
import java.util.concurrent.ConcurrentMap;
43
import java.util.concurrent.ConcurrentMap;
44
import org.netbeans.api.lexer.Language;
45
import org.netbeans.api.lexer.TokenId;
46
import org.netbeans.api.lexer.TokenSequence;
47
import org.netbeans.cnd.api.lexer.CndLexerUtilities;
48
import org.netbeans.cnd.api.lexer.CppTokenId;
42
import org.netbeans.lib.editor.util.CharSequenceUtilities;
49
import org.netbeans.lib.editor.util.CharSequenceUtilities;
43
import org.netbeans.modules.cnd.api.model.CsmErrorDirective;
50
import org.netbeans.modules.cnd.api.model.CsmErrorDirective;
44
import org.netbeans.modules.cnd.api.model.CsmFile;
51
import org.netbeans.modules.cnd.api.model.CsmFile;
45
import org.netbeans.modules.cnd.api.model.CsmInclude;
52
import org.netbeans.modules.cnd.api.model.CsmInclude;
46
import org.netbeans.modules.cnd.api.model.CsmOffsetable;
53
import org.netbeans.modules.cnd.api.model.CsmOffsetable;
47
import org.netbeans.modules.cnd.api.model.CsmUID;
54
import org.netbeans.modules.cnd.api.model.CsmUID;
55
import org.netbeans.modules.cnd.api.model.services.CsmCacheManager;
56
import org.netbeans.modules.cnd.api.model.services.CsmCacheMap;
48
import org.netbeans.modules.cnd.api.model.services.CsmCompilationUnit;
57
import org.netbeans.modules.cnd.api.model.services.CsmCompilationUnit;
49
import org.netbeans.modules.cnd.api.model.services.CsmFileInfoQuery;
58
import org.netbeans.modules.cnd.api.model.services.CsmFileInfoQuery;
50
import org.netbeans.modules.cnd.api.model.xref.CsmReference;
59
import org.netbeans.modules.cnd.api.model.xref.CsmReference;
Lines 85-90 Link Here
85
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.cnd.api.model.services.CsmFileInfoQuery.class)
94
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.cnd.api.model.services.CsmFileInfoQuery.class)
86
public final class FileInfoQueryImpl extends CsmFileInfoQuery {
95
public final class FileInfoQueryImpl extends CsmFileInfoQuery {
87
    
96
    
97
    private static final Callable<CsmCacheMap> TOKEN_SEQUENCE_CACHE_INITIALIZER = new Callable<CsmCacheMap>() {
98
99
        @Override
100
        public CsmCacheMap call() {
101
            return new CsmCacheMap("FileInfoQueryImpl: get token sequence", 1); // NOI18N
102
        }
103
104
    };
105
    
88
    @Override
106
    @Override
89
    public boolean isCpp98OrLater(CsmFile csmFile) {
107
    public boolean isCpp98OrLater(CsmFile csmFile) {
90
        if (csmFile != null) {
108
        if (csmFile != null) {
Lines 416-421 Link Here
416
        }
434
        }
417
        return Pair.of(NativeFileItem.Language.OTHER, NativeFileItem.LanguageFlavor.UNKNOWN);
435
        return Pair.of(NativeFileItem.Language.OTHER, NativeFileItem.LanguageFlavor.UNKNOWN);
418
    }
436
    }
437
438
    @Override
439
    public Language getFileLexerLanguage(CsmFile file) {
440
        Pair<NativeFileItem.Language, NativeFileItem.LanguageFlavor> fileLanguageFlavor = getFileLanguageFlavor(file);
441
        switch (fileLanguageFlavor.first()) {
442
            case C:
443
                return CppTokenId.languageC();
444
            case CPP:
445
                return CppTokenId.languageCpp();
446
            case C_HEADER:
447
                return CppTokenId.languageHeader();
448
            default:
449
                return null;
450
        }
451
    }
452
    
453
    /**
454
     * returns C/C++/Preprocessor tokens sequence for text
455
     * @param file cpp source file
456
     * @param offset offset
457
     * @param lexPP if <code>true</code> and offset is in preprocessor directive then return tokens sequence of this
458
     * directive. If <code>false</code> and offset is in preprocessor directive do not dive into embedding
459
     * @param backwardBias @see TokenHierarchy.embeddedTokenSequences
460
     * If <code>true</code> the backward lying token will
461
     *   be used in case that the <code>offset</code> specifies position between
462
     *   two tokens. If <code>false</code> the forward lying token will be used.     * 
463
     * @return token sequence positioned on token with offset (no need to call moveNext()/movePrevious() before token())
464
     */
465
    @Override
466
    public TokenSequence<TokenId> getCppTokenSequence(final CsmFile file, final int offset, boolean lexPP, boolean backwardBias) {
467
        Language lexerLanguage = getFileLexerLanguage(file);
468
        CsmCacheMap cache = getTokenSequenceCache();
469
        TokenSequenceRequest key =  new TokenSequenceRequest(lexerLanguage, getFileVersion(file), file);
470
        boolean[] found = new boolean[] { false };
471
        Object cached = CsmCacheMap.getFromCache(cache, key, found);
472
        if (cached != null && found[0]) {
473
            return (TokenSequence<TokenId>) cached;
474
        } else {
475
            long time = System.currentTimeMillis();
476
            TokenSequence<TokenId> cppTokenSequence = CndLexerUtilities.getCppTokenSequence(file.getText(), offset, lexerLanguage, lexPP, backwardBias);
477
            time = System.currentTimeMillis() - time;
478
            if (cache != null) {
479
                cache.put(key, CsmCacheMap.toValue(cppTokenSequence, time));
480
            }
481
            return cppTokenSequence;
482
        }
483
    }
419
    
484
    
420
    private int getLangPriority(NativeFileItem.Language lang) {
485
    private int getLangPriority(NativeFileItem.Language lang) {
421
        if (lang == null) {
486
        if (lang == null) {
Lines 664-667 Link Here
664
        }
729
        }
665
        return new int[]{0, 0};
730
        return new int[]{0, 0};
666
    }        
731
    }        
732
    
733
    private CsmCacheMap getTokenSequenceCache() {
734
        return CsmCacheManager.getClientCache(TokenSequenceRequest.class, TOKEN_SEQUENCE_CACHE_INITIALIZER);
735
    }
736
    
737
    private static final class TokenSequenceRequest {
738
        
739
        private final Language language;
740
        
741
        private final long fileVersion;
742
        
743
        private final CsmFile file;
744
745
        public TokenSequenceRequest(Language language, long fileVersion, CsmFile file) {
746
            this.language = language;
747
            this.fileVersion = fileVersion;
748
            this.file = file;
749
        }
750
751
        @Override
752
        public int hashCode() {
753
            int hash = 5;
754
            hash = 71 * hash + Objects.hashCode(this.language);
755
            hash = 71 * hash + (int) (this.fileVersion ^ (this.fileVersion >>> 32));
756
            hash = 71 * hash + Objects.hashCode(this.file);
757
            return hash;
758
        }
759
760
        @Override
761
        public boolean equals(Object obj) {
762
            if (this == obj) {
763
                return true;
764
            }
765
            if (obj == null) {
766
                return false;
767
            }
768
            if (getClass() != obj.getClass()) {
769
                return false;
770
            }
771
            final TokenSequenceRequest other = (TokenSequenceRequest) obj;
772
            if (this.fileVersion != other.fileVersion) {
773
                return false;
774
            }
775
            if (!Objects.equals(this.language, other.language)) {
776
                return false;
777
            }
778
            if (!Objects.equals(this.file, other.file)) {
779
                return false;
780
            }
781
            return true;
782
        }
783
    }
667
}
784
}
(-)a/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/impl/services/MacroExpansionDocProviderImpl.java (+20 lines)
Lines 229-234 Link Here
229
        }
229
        }
230
        return originalOffset;
230
        return originalOffset;
231
    }
231
    }
232
    
233
    @Override
234
    public int getOffsetInExpandedText(CsmFile expandedFile, int originalOffset) {
235
        Object o = expandedFile.getProperty(MACRO_EXPANSION_OFFSET_TRANSFORMER);
236
        if (o != null && o instanceof TransformationTable) {
237
            TransformationTable tt = (TransformationTable) o;
238
            return tt.getOutOffset(originalOffset);
239
        }
240
        return originalOffset;
241
    }
232
242
233
    @Override
243
    @Override
234
    public int getOffsetInOriginalText(Document expandedDoc, int expandedOffset) {
244
    public int getOffsetInOriginalText(Document expandedDoc, int expandedOffset) {
Lines 239-244 Link Here
239
        }
249
        }
240
        return expandedOffset;
250
        return expandedOffset;
241
    }
251
    }
252
    
253
    @Override
254
    public int getOffsetInOriginalText(CsmFile expandedFile, int expandedOffset) {
255
        Object o = expandedFile.getProperty(MACRO_EXPANSION_OFFSET_TRANSFORMER);
256
        if (o != null && o instanceof TransformationTable) {
257
            TransformationTable tt = (TransformationTable) o;
258
            return tt.getInOffset(expandedOffset);
259
        }
260
        return expandedOffset;
261
    }
242
262
243
    @Override
263
    @Override
244
    public int getNextMacroExpansionStartOffset(Document expandedDoc, int expandedOffset) {
264
    public int getNextMacroExpansionStartOffset(Document expandedDoc, int expandedOffset) {

Return to bug 255176