@Override public RType getSubscriptionType(List<RExpression> indices, boolean isSingleBracket) { if (indices.isEmpty()) { return this; } if (indices.size() > 1) { return RUnknownType.INSTANCE; } RExpression index = indices.get(0); RType type = RUnknownType.INSTANCE; String indexName = null; if (index instanceof RStringLiteralExpression) { String quoted = index.getText(); indexName = quoted.substring(1, quoted.length() - 1); type = getFieldType(indexName); } if (index instanceof RNumericLiteralExpression) { try { int i = Integer.parseInt(index.getText()); TypeDescriptor descriptor = getFieldDescriptor(i - 1); indexName = descriptor.myName; type = descriptor.myType; } catch (NumberFormatException e) { // Do nothing } } if (!RNullType.class.isInstance(type) && !RUnknownType.class.isInstance(type) && isSingleBracket) { RListType listType = new RListType(); listType.addField(indexName, type); type = listType; } return type; }
// handles assignment to subscription expression @Override public RType afterSubscriptionType( List<RExpression> indices, RType valueType, boolean isSingleBracket) { if (indices.isEmpty()) { return this; } if (indices.size() > 1) { return RUnknownType.INSTANCE; } if (isSingleBracket && valueType instanceof RListType) { RListType list = (RListType) valueType; if (!list.myPrecise) { return RUnknownType.INSTANCE; } if (list.myPositionalTypes.isEmpty()) { return RUnknownType.INSTANCE; } valueType = list.myPositionalTypes.get(0).myType; } RExpression index = indices.get(0); RListType resultType = new RListType(this); if (index instanceof RStringLiteralExpression) { String quoted = index.getText(); String indexName = quoted.substring(1, quoted.length() - 1); if (valueType instanceof RNullType) { resultType.removeField(indexName); } else { resultType.addField(indexName, valueType); } } if (index instanceof RNumericLiteralExpression) { try { int i = Integer.parseInt(index.getText()); if (valueType instanceof RNullType) { resultType.removeField(i - 1); } else { resultType.addField(i - 1, valueType); } } catch (NumberFormatException e) { // do nothing } } return resultType; }
@Override public RType afterMemberType(String tag, RType valueType) { RListType clone = clone(); if (valueType instanceof RNullType) { clone.removeField(tag); } else { clone.addField(tag, valueType); } return clone; }