Lines 65-79
Link Here
|
65 |
import org.netbeans.cnd.api.lexer.CppTokenId; |
65 |
import org.netbeans.cnd.api.lexer.CppTokenId; |
66 |
import org.netbeans.modules.cnd.api.model.CsmClass; |
66 |
import org.netbeans.modules.cnd.api.model.CsmClass; |
67 |
import org.netbeans.modules.cnd.api.model.CsmClassifier; |
67 |
import org.netbeans.modules.cnd.api.model.CsmClassifier; |
|
|
68 |
import org.netbeans.modules.cnd.api.model.CsmConstructor; |
68 |
import org.netbeans.modules.cnd.api.model.CsmDeclaration; |
69 |
import org.netbeans.modules.cnd.api.model.CsmDeclaration; |
69 |
import org.netbeans.modules.cnd.api.model.CsmField; |
70 |
import org.netbeans.modules.cnd.api.model.CsmField; |
70 |
import org.netbeans.modules.cnd.api.model.CsmFile; |
71 |
import org.netbeans.modules.cnd.api.model.CsmFile; |
71 |
import org.netbeans.modules.cnd.api.model.CsmFunction; |
72 |
import org.netbeans.modules.cnd.api.model.CsmFunction; |
72 |
import org.netbeans.modules.cnd.api.model.CsmFunctional; |
73 |
import org.netbeans.modules.cnd.api.model.CsmFunctional; |
73 |
import org.netbeans.modules.cnd.api.model.CsmMember; |
74 |
import org.netbeans.modules.cnd.api.model.CsmMember; |
|
|
75 |
import org.netbeans.modules.cnd.api.model.CsmObject; |
74 |
import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration; |
76 |
import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration; |
75 |
import org.netbeans.modules.cnd.api.model.CsmParameter; |
77 |
import org.netbeans.modules.cnd.api.model.CsmParameter; |
|
|
78 |
import org.netbeans.modules.cnd.api.model.CsmSpecializationParameter; |
76 |
import org.netbeans.modules.cnd.api.model.CsmTemplate; |
79 |
import org.netbeans.modules.cnd.api.model.CsmTemplate; |
|
|
80 |
import org.netbeans.modules.cnd.api.model.CsmTemplateParameter; |
77 |
import org.netbeans.modules.cnd.api.model.CsmType; |
81 |
import org.netbeans.modules.cnd.api.model.CsmType; |
78 |
import org.netbeans.modules.cnd.api.model.CsmVariable; |
82 |
import org.netbeans.modules.cnd.api.model.CsmVariable; |
79 |
import org.netbeans.modules.cnd.api.model.deep.CsmReturnStatement; |
83 |
import org.netbeans.modules.cnd.api.model.deep.CsmReturnStatement; |
Lines 81-100
Link Here
|
81 |
import org.netbeans.modules.cnd.api.model.deep.CsmStatement.Kind; |
85 |
import org.netbeans.modules.cnd.api.model.deep.CsmStatement.Kind; |
82 |
import org.netbeans.modules.cnd.api.model.services.CsmClassifierResolver; |
86 |
import org.netbeans.modules.cnd.api.model.services.CsmClassifierResolver; |
83 |
import org.netbeans.modules.cnd.api.model.services.CsmInheritanceUtilities; |
87 |
import org.netbeans.modules.cnd.api.model.services.CsmInheritanceUtilities; |
|
|
88 |
import org.netbeans.modules.cnd.api.model.services.CsmInstantiationProvider; |
84 |
import org.netbeans.modules.cnd.api.model.services.CsmMacroExpansion; |
89 |
import org.netbeans.modules.cnd.api.model.services.CsmMacroExpansion; |
|
|
90 |
import org.netbeans.modules.cnd.api.model.services.CsmTypes; |
91 |
import org.netbeans.modules.cnd.api.model.util.CsmBaseUtilities; |
85 |
import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities; |
92 |
import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities; |
86 |
import org.netbeans.modules.cnd.api.model.util.UIDs; |
93 |
import org.netbeans.modules.cnd.api.model.util.UIDs; |
87 |
import org.netbeans.modules.cnd.completion.cplusplus.CsmFinderFactory; |
94 |
import org.netbeans.modules.cnd.completion.cplusplus.CsmFinderFactory; |
|
|
95 |
import org.netbeans.modules.cnd.completion.cplusplus.ext.CsmCompletionQuery.Context; |
88 |
import org.netbeans.modules.cnd.completion.csm.CompletionUtilities; |
96 |
import org.netbeans.modules.cnd.completion.csm.CompletionUtilities; |
89 |
import org.netbeans.modules.cnd.completion.csm.CsmContext; |
97 |
import org.netbeans.modules.cnd.completion.csm.CsmContext; |
90 |
import org.netbeans.modules.cnd.completion.csm.CsmContextUtilities; |
98 |
import org.netbeans.modules.cnd.completion.csm.CsmContextUtilities; |
91 |
import org.netbeans.modules.cnd.completion.csm.CsmOffsetResolver; |
99 |
import org.netbeans.modules.cnd.completion.csm.CsmOffsetResolver; |
92 |
import org.netbeans.modules.cnd.completion.csm.CsmOffsetUtilities; |
100 |
import org.netbeans.modules.cnd.completion.csm.CsmOffsetUtilities; |
93 |
import org.netbeans.modules.cnd.completion.impl.xref.FileReferencesContext; |
101 |
import org.netbeans.modules.cnd.completion.impl.xref.FileReferencesContext; |
|
|
102 |
import org.netbeans.modules.cnd.modelutil.CsmUtilities; |
94 |
import org.netbeans.modules.editor.NbEditorUtilities; |
103 |
import org.netbeans.modules.editor.NbEditorUtilities; |
|
|
104 |
import org.netbeans.spi.editor.completion.CompletionItem; |
95 |
import org.netbeans.spi.editor.completion.CompletionProvider; |
105 |
import org.netbeans.spi.editor.completion.CompletionProvider; |
96 |
import org.openide.filesystems.FileObject; |
106 |
import org.openide.filesystems.FileObject; |
97 |
import org.openide.loaders.DataObject; |
107 |
import org.openide.loaders.DataObject; |
|
|
108 |
import org.openide.util.Pair; |
98 |
|
109 |
|
99 |
/** |
110 |
/** |
100 |
* |
111 |
* |
Lines 378-392
Link Here
|
378 |
/** Filter the list of the methods (usually returned from |
389 |
/** Filter the list of the methods (usually returned from |
379 |
* Finder.findMethods()) or the list of the constructors |
390 |
* Finder.findMethods()) or the list of the constructors |
380 |
* by the given parameter specification. |
391 |
* by the given parameter specification. |
|
|
392 |
* @param ctx - completion context |
381 |
* @param methodList list of the methods. They should have the same |
393 |
* @param methodList list of the methods. They should have the same |
382 |
* name but in fact they don't have to. |
394 |
* name but in fact they don't have to. |
|
|
395 |
* @param exp - instantiation params |
383 |
* @param parmTypes parameter types specification. If set to null, no filtering |
396 |
* @param parmTypes parameter types specification. If set to null, no filtering |
384 |
* is performed and the same list is returned. If a particular |
397 |
* is performed and the same list is returned. If a particular |
385 |
* @param acceptMoreParameters useful for code completion to get |
398 |
* @param acceptMoreParameters useful for code completion to get |
386 |
* even the methods with more parameters. |
399 |
* even the methods with more parameters. |
387 |
*/ |
400 |
*/ |
388 |
public static <T extends CsmFunctional> Collection<T> filterMethods(Collection<T> methodList, List parmTypeList, |
401 |
static <T extends CsmFunctional> Collection<T> filterMethods(Context ctx, |
389 |
boolean acceptMoreParameters, boolean acceptIfSameNumberParams) { |
402 |
Collection<T> methodList, |
|
|
403 |
CsmCompletionExpression exp, |
404 |
List parmTypeList, |
405 |
boolean acceptMoreParameters, |
406 |
boolean acceptIfSameNumberParams |
407 |
) { |
390 |
Collection<T> result = filterMethods(methodList, parmTypeList, acceptMoreParameters, acceptIfSameNumberParams, false); |
408 |
Collection<T> result = filterMethods(methodList, parmTypeList, acceptMoreParameters, acceptIfSameNumberParams, false); |
391 |
if (result.size() > 1) { |
409 |
if (result.size() > 1) { |
392 |
// it seems that this call couldn't filter anything |
410 |
// it seems that this call couldn't filter anything |
Lines 394-400
Link Here
|
394 |
|
412 |
|
395 |
// perform more accurate filtering if it is a strict request (for navigation probably) |
413 |
// perform more accurate filtering if it is a strict request (for navigation probably) |
396 |
if (!acceptMoreParameters && acceptIfSameNumberParams) { |
414 |
if (!acceptMoreParameters && acceptIfSameNumberParams) { |
397 |
result = accurateFilterMethods(result, parmTypeList); |
415 |
result = accurateFilterMethods(ctx, result, exp, parmTypeList); |
398 |
} |
416 |
} |
399 |
} |
417 |
} |
400 |
return result; |
418 |
return result; |
Lines 490-501
Link Here
|
490 |
* Please note: This method is designed to be called after preliminary filtering. |
508 |
* Please note: This method is designed to be called after preliminary filtering. |
491 |
* But this is not a necessary requirement. |
509 |
* But this is not a necessary requirement. |
492 |
* |
510 |
* |
|
|
511 |
* @param ctx - completion context |
493 |
* @param methods |
512 |
* @param methods |
494 |
* @param paramTypes |
513 |
* @param paramTypes |
495 |
* |
514 |
* |
496 |
* @return candidates |
515 |
* @return candidates |
497 |
*/ |
516 |
*/ |
498 |
private static <T extends CsmFunctional> Collection<T> accurateFilterMethods(Collection<T> methods, List paramTypes) { |
517 |
private static <T extends CsmFunctional> Collection<T> accurateFilterMethods(Context ctx, Collection<T> methods, CsmCompletionExpression exp, List paramTypes) { |
499 |
if (methods.size() <= 1) { |
518 |
if (methods.size() <= 1) { |
500 |
return methods; |
519 |
return methods; |
501 |
} |
520 |
} |
Lines 551-558
Link Here
|
551 |
break; |
570 |
break; |
552 |
} |
571 |
} |
553 |
} |
572 |
} |
554 |
prev = candidate; |
573 |
|
555 |
result.add(candidate.function); |
574 |
boolean validCandidate = true; |
|
|
575 |
|
576 |
if (CsmKindUtilities.isTemplate(candidate.function)) { |
577 |
// we should check if this function is viable |
578 |
CsmType retType = extractFunctionType(ctx, Arrays.asList(candidate.function), exp, paramTypes); |
579 |
CsmClassifier cls = retType != null ? CsmBaseUtilities.getClassifier(retType, ctx.getContextFile(), ctx.getEndOffset(), true) : null; |
580 |
validCandidate = (cls != null && cls.isValid()); |
581 |
} |
582 |
|
583 |
if (validCandidate) { |
584 |
prev = candidate; |
585 |
result.add(candidate.function); |
586 |
} |
556 |
} |
587 |
} |
557 |
|
588 |
|
558 |
return result.isEmpty() ? methods : result; |
589 |
return result.isEmpty() ? methods : result; |
Lines 906-911
Link Here
|
906 |
} |
937 |
} |
907 |
return false; |
938 |
return false; |
908 |
} |
939 |
} |
|
|
940 |
|
941 |
static CsmType extractFunctionType(Context context, Collection<? extends CsmFunctional> mtdList, CsmCompletionExpression genericNameExp, List<CsmType> typeList) { |
942 |
CsmType out = null; |
943 |
if (mtdList.isEmpty()) { |
944 |
return null; |
945 |
} |
946 |
for (CsmFunctional fun : mtdList) { |
947 |
CsmObject entity = fun; |
948 |
|
949 |
if (CsmKindUtilities.isConstructor(entity)) { |
950 |
entity = ((CsmConstructor) entity).getContainingClass(); |
951 |
} |
952 |
|
953 |
if (CsmKindUtilities.isTemplate(entity)) { |
954 |
CsmObject inst = createInstantiation(context, (CsmTemplate) entity, genericNameExp, typeList); |
955 |
if (CsmKindUtilities.isFunction(inst) || CsmKindUtilities.isClassifier(inst)) { |
956 |
entity = inst; |
957 |
} |
958 |
} |
959 |
|
960 |
if (CsmKindUtilities.isFunctional(entity)) { |
961 |
out = ((CsmFunctional) entity).getReturnType(); |
962 |
} else if (CsmKindUtilities.isClassifier(entity)) { |
963 |
out = CsmCompletion.createType((CsmClassifier) entity, 0, 0, 0, false); |
964 |
} |
965 |
if (out != null) { |
966 |
break; |
967 |
} |
968 |
} |
969 |
return out; |
970 |
} |
971 |
|
972 |
static CsmObject createInstantiation(Context context, CsmTemplate template, CsmCompletionExpression exp, List<CsmType> typeList) { |
973 |
if (exp != null || !typeList.isEmpty()) { |
974 |
CsmInstantiationProvider ip = CsmInstantiationProvider.getDefault(); |
975 |
List<CsmSpecializationParameter> params = new ArrayList<CsmSpecializationParameter>(); |
976 |
params.addAll(collectInstantiationParameters(context, ip, exp)); |
977 |
if (CsmKindUtilities.isFunction(template)) { |
978 |
params.addAll(collectInstantiationParameters(ip, (CsmFunction)template, params.size(), typeList)); |
979 |
} |
980 |
if (!params.isEmpty()) { |
981 |
return ip.instantiate(template, params); |
982 |
} |
983 |
} |
984 |
return null; |
985 |
} |
986 |
|
987 |
static List<CsmSpecializationParameter> collectInstantiationParameters(Context context, CsmInstantiationProvider ip, CsmCompletionExpression exp) { |
988 |
if (exp != null) { |
989 |
List<CsmSpecializationParameter> params = new ArrayList<CsmSpecializationParameter>(); |
990 |
if (exp.getExpID() == CsmCompletionExpression.GENERIC_TYPE) { |
991 |
int paramsNumber = exp.getParameterCount() - 1; |
992 |
for (int i = 0; i < paramsNumber; i++) { |
993 |
CsmCompletionExpression paramInst = exp.getParameter(i + 1); |
994 |
if (paramInst != null) { |
995 |
switch (paramInst.getExpID()) { |
996 |
case CsmCompletionExpression.CONSTANT: |
997 |
params.add(ip.createExpressionBasedSpecializationParameter(paramInst.getTokenText(0), |
998 |
context.getContextFile(), paramInst.getTokenOffset(0), paramInst.getTokenOffset(0) + paramInst.getTokenLength(0))); |
999 |
break; |
1000 |
default: |
1001 |
CsmType type = null; |
1002 |
|
1003 |
if (!isExpression(paramInst)) { |
1004 |
type = context.resolveType(paramInst); |
1005 |
if (type != null) { |
1006 |
List<? extends CompletionItem> candidates = context.resolveNextExp(paramInst); |
1007 |
if (candidates != null && (candidates.get(0) instanceof CsmResultItem.VariableResultItem)) { |
1008 |
type = null; |
1009 |
} |
1010 |
} |
1011 |
} |
1012 |
|
1013 |
if (type != null) { |
1014 |
params.add(ip.createTypeBasedSpecializationParameter(type)); |
1015 |
} else { |
1016 |
RenderedExpression renderedExpression = renderExpression(paramInst); |
1017 |
params.add(ip.createExpressionBasedSpecializationParameter( |
1018 |
renderedExpression.text, |
1019 |
context.getContextFile(), |
1020 |
renderedExpression.startOffset, |
1021 |
renderedExpression.endOffset |
1022 |
)); |
1023 |
} |
1024 |
} |
1025 |
} else { |
1026 |
break; |
1027 |
} |
1028 |
} |
1029 |
} |
1030 |
return params; |
1031 |
} |
1032 |
return Collections.emptyList(); |
1033 |
} |
1034 |
|
1035 |
static List<CsmSpecializationParameter> collectInstantiationParameters(CsmInstantiationProvider ip, CsmFunction function, int explicitelyMappedSize, List<CsmType> typeList) { |
1036 |
if (CsmKindUtilities.isTemplate(function)) { |
1037 |
List<CsmSpecializationParameter> result = new ArrayList<CsmSpecializationParameter>(); |
1038 |
|
1039 |
CsmTemplate template = (CsmTemplate) function; |
1040 |
List<CsmTemplateParameter> templateParams = template.getTemplateParameters(); |
1041 |
|
1042 |
if (templateParams.size() > explicitelyMappedSize) { |
1043 |
Map<CsmTemplateParameter, CsmType> paramsMap = gatherTemplateParamsMap(function, typeList); |
1044 |
|
1045 |
for (int i = explicitelyMappedSize; i < templateParams.size(); i++) { |
1046 |
CsmTemplateParameter param = templateParams.get(i); |
1047 |
CsmType mappedType = paramsMap.get(param); |
1048 |
if (mappedType != null) { |
1049 |
result.add(ip.createTypeBasedSpecializationParameter(mappedType)); |
1050 |
} else { |
1051 |
// error |
1052 |
return result; |
1053 |
} |
1054 |
} |
1055 |
} |
1056 |
|
1057 |
return result; |
1058 |
} |
1059 |
return Collections.emptyList(); |
1060 |
} |
1061 |
|
1062 |
static Map<CsmTemplateParameter, CsmType> gatherTemplateParamsMap(CsmFunction function, List<CsmType> typeList) { |
1063 |
assert CsmKindUtilities.isTemplate(function) : "Attempt to gather template parameters map from non-template function"; // NOI18N |
1064 |
CsmTemplate template = (CsmTemplate) function; |
1065 |
|
1066 |
Map<CsmTemplateParameter, CsmType> map = new HashMap<CsmTemplateParameter, CsmType>(); |
1067 |
|
1068 |
for (CsmTemplateParameter templateParam : template.getTemplateParameters()) { |
1069 |
int paramIndex = 0; |
1070 |
for (CsmParameter param : function.getParameters()) { |
1071 |
if (paramIndex >= typeList.size()) { |
1072 |
break; |
1073 |
} |
1074 |
CsmType paramType = param.getType(); |
1075 |
CsmType calculatedType = calcTypeFromParameter(templateParam, paramType, typeList.get(paramIndex)); |
1076 |
if (calculatedType != null) { |
1077 |
map.put(templateParam, calculatedType); |
1078 |
} |
1079 |
paramIndex++; |
1080 |
} |
1081 |
} |
1082 |
|
1083 |
return map; |
1084 |
} |
1085 |
|
1086 |
static CsmType calcTypeFromParameter(CsmTemplateParameter templateParam, CsmType paramType, CsmType passedType) { |
1087 |
if (paramType != null) { |
1088 |
CsmClassifier cls = paramType.getClassifier(); |
1089 |
if (cls != null && cls.getQualifiedName().toString().equals(templateParam.getQualifiedName().toString())) { |
1090 |
boolean hasChanges = false; |
1091 |
|
1092 |
boolean newConst = false; |
1093 |
int newReference = CsmTypes.TypeDescriptor.NON_REFERENCE; |
1094 |
int newPtrDepth = 0; |
1095 |
int newArrayDepth = 0; |
1096 |
|
1097 |
CsmType underlyingType = CsmUtilities.iterateTypeChain(passedType, new CsmUtilities.ConstantPredicate<CsmType>(false)); |
1098 |
|
1099 |
if (paramType.isConst()) { |
1100 |
if (underlyingType.isConst()) { |
1101 |
hasChanges = true; |
1102 |
newConst = false; |
1103 |
} else { |
1104 |
return null; |
1105 |
} |
1106 |
} |
1107 |
|
1108 |
if (paramType.isPointer()) { |
1109 |
if (paramType.getPointerDepth() <= underlyingType.getPointerDepth()) { |
1110 |
hasChanges = true; |
1111 |
newPtrDepth = underlyingType.getPointerDepth() - paramType.getPointerDepth(); |
1112 |
} else { |
1113 |
return null; |
1114 |
} |
1115 |
} |
1116 |
|
1117 |
if (paramType.isReference()) { |
1118 |
if (underlyingType.isReference()) { |
1119 |
hasChanges = true; |
1120 |
newReference = CsmTypes.TypeDescriptor.NON_REFERENCE; |
1121 |
} else { |
1122 |
return null; |
1123 |
} |
1124 |
} |
1125 |
|
1126 |
if (paramType.isRValueReference()) { |
1127 |
if (underlyingType.isRValueReference()) { |
1128 |
hasChanges = true; |
1129 |
newReference = CsmTypes.TypeDescriptor.NON_REFERENCE; |
1130 |
} else { |
1131 |
return null; |
1132 |
} |
1133 |
} |
1134 |
|
1135 |
if (hasChanges) { |
1136 |
CsmTypes.TypeDescriptor td = new CsmTypes.TypeDescriptor( |
1137 |
newConst, |
1138 |
newReference, |
1139 |
newPtrDepth, |
1140 |
newArrayDepth |
1141 |
); |
1142 |
|
1143 |
return CsmTypes.createType(underlyingType, td); |
1144 |
} |
1145 |
|
1146 |
return passedType; |
1147 |
} |
1148 |
} |
1149 |
return null; |
1150 |
} |
1151 |
|
1152 |
static RenderedExpression renderExpression(CsmCompletionExpression expr) { |
1153 |
if (expr == null) { |
1154 |
return null; |
1155 |
} |
1156 |
switch (expr.getExpID()) { |
1157 |
case CsmCompletionExpression.GENERIC_TYPE: { |
1158 |
StringBuilder sb = new StringBuilder(); |
1159 |
int startExpOffset = expr.getTokenOffset(0); |
1160 |
int endExpOffset = startExpOffset; |
1161 |
|
1162 |
for (int paramIndex = 0; paramIndex < expr.getParameterCount(); paramIndex++) { |
1163 |
RenderedExpression current = renderExpression(expr.getParameter(paramIndex)); |
1164 |
|
1165 |
sb.append(current.text); |
1166 |
|
1167 |
if (paramIndex > 0) { |
1168 |
if (paramIndex < expr.getParameterCount() - 1) { |
1169 |
sb.append(","); // NOI18N |
1170 |
} else { |
1171 |
sb.append(">"); // NOI18N |
1172 |
} |
1173 |
endExpOffset++; |
1174 |
} else { |
1175 |
sb.append(expr.getTokenText(0)); |
1176 |
} |
1177 |
|
1178 |
endExpOffset = current.endOffset; |
1179 |
} |
1180 |
|
1181 |
return new RenderedExpression(sb.toString(), startExpOffset, endExpOffset); |
1182 |
} |
1183 |
|
1184 |
case CsmCompletionExpression.UNARY_OPERATOR: |
1185 |
case CsmCompletionExpression.OPERATOR: |
1186 |
case CsmCompletionExpression.SCOPE: { |
1187 |
StringBuilder sb = new StringBuilder(); |
1188 |
int startExpOffset = -1; |
1189 |
int endExprOffset = -1; |
1190 |
|
1191 |
int paramCount = expr.getParameterCount(); |
1192 |
int tokenCount = expr.getTokenCount(); |
1193 |
int paramIndex = 0; |
1194 |
int tokenIndex = 0; |
1195 |
|
1196 |
RenderedExpression renderedParam = null; |
1197 |
RenderedExpression renderedToken = null; |
1198 |
boolean lastWasParam = false; |
1199 |
boolean lastWasToken = false; |
1200 |
|
1201 |
boolean entityChanged = true; |
1202 |
|
1203 |
while (entityChanged) { |
1204 |
entityChanged = false; |
1205 |
|
1206 |
if (renderedParam == null && paramIndex < paramCount) { |
1207 |
renderedParam = renderExpression(expr.getParameter(paramIndex)); |
1208 |
paramIndex++; |
1209 |
} |
1210 |
|
1211 |
if (renderedToken == null && tokenIndex < tokenCount) { |
1212 |
renderedToken = new RenderedExpression( |
1213 |
expr.getTokenText(tokenIndex).toString(), |
1214 |
expr.getTokenOffset(tokenIndex), |
1215 |
expr.getTokenOffset(tokenIndex) + expr.getTokenLength(tokenIndex) |
1216 |
); |
1217 |
tokenIndex++; |
1218 |
} |
1219 |
|
1220 |
RenderedExpression chosenExpression; |
1221 |
|
1222 |
if (renderedParam != null && renderedToken != null) { |
1223 |
if (renderedParam.startOffset < renderedToken.startOffset) { |
1224 |
chosenExpression = renderedParam; |
1225 |
} else { |
1226 |
chosenExpression = renderedToken; |
1227 |
} |
1228 |
} else if (renderedToken == null) { |
1229 |
chosenExpression = renderedParam; |
1230 |
} else { |
1231 |
chosenExpression = renderedToken; |
1232 |
} |
1233 |
|
1234 |
if (chosenExpression != null) { |
1235 |
if (chosenExpression == renderedParam) { |
1236 |
renderedParam = null; |
1237 |
entityChanged = !lastWasParam; |
1238 |
lastWasParam = true; |
1239 |
lastWasToken = false; |
1240 |
} else { |
1241 |
renderedToken = null; |
1242 |
entityChanged = !lastWasToken; |
1243 |
lastWasToken = true; |
1244 |
lastWasParam = false; |
1245 |
} |
1246 |
|
1247 |
if (entityChanged) { |
1248 |
sb.append(chosenExpression.text); |
1249 |
if (startExpOffset == -1) { |
1250 |
startExpOffset = chosenExpression.startOffset; |
1251 |
} |
1252 |
endExprOffset = chosenExpression.endOffset; |
1253 |
} |
1254 |
} |
1255 |
} |
1256 |
|
1257 |
return new RenderedExpression(sb.toString(), startExpOffset, endExprOffset); |
1258 |
} |
1259 |
|
1260 |
default: { |
1261 |
return new RenderedExpression( |
1262 |
expr.getTokenText(0), |
1263 |
expr.getTokenOffset(0), |
1264 |
expr.getTokenOffset(0) + expr.getTokenLength(0) |
1265 |
); |
1266 |
} |
1267 |
} |
1268 |
} |
909 |
|
1269 |
|
910 |
CsmType findExactVarType(CsmFile file, String var, int docPos, FileReferencesContext refContext) { |
1270 |
CsmType findExactVarType(CsmFile file, String var, int docPos, FileReferencesContext refContext) { |
911 |
if (file == null) { |
1271 |
if (file == null) { |
Lines 1001-1007
Link Here
|
1001 |
} |
1361 |
} |
1002 |
} |
1362 |
} |
1003 |
return null; |
1363 |
return null; |
1004 |
} |
1364 |
} |
|
|
1365 |
|
1366 |
private static boolean isExpression(CsmCompletionExpression expression) { |
1367 |
return expression.getExpID() == CsmCompletionExpression.OPERATOR || |
1368 |
expression.getExpID() == CsmCompletionExpression.UNARY_OPERATOR; |
1369 |
} |
1005 |
|
1370 |
|
1006 |
private int findLCurlsNumberBeforPosition(String s, int pos) { |
1371 |
private int findLCurlsNumberBeforPosition(String s, int pos) { |
1007 |
int cursor = -1; |
1372 |
int cursor = -1; |
Lines 1075-1078
Link Here
|
1075 |
public void changedUpdate(DocumentEvent e) { |
1440 |
public void changedUpdate(DocumentEvent e) { |
1076 |
this.lastSeparatorOffset = -1; |
1441 |
this.lastSeparatorOffset = -1; |
1077 |
} |
1442 |
} |
|
|
1443 |
|
1444 |
|
1445 |
static class RenderedExpression { |
1446 |
|
1447 |
public final String text; |
1448 |
|
1449 |
public final int startOffset; |
1450 |
|
1451 |
public final int endOffset; |
1452 |
|
1453 |
public RenderedExpression(String text, int startOffset, int endOffset) { |
1454 |
this.text = text; |
1455 |
this.startOffset = startOffset; |
1456 |
this.endOffset = endOffset; |
1457 |
} |
1458 |
|
1459 |
@Override |
1460 |
public String toString() { |
1461 |
return text + "[" + startOffset + "," + endOffset + "]"; // NOI18N |
1462 |
} |
1463 |
} |
1078 |
} |
1464 |
} |