This is an automated email from the ASF dual-hosted git repository.

sdedic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 6cc17217f4 Fixed key escaping; fixed list/map property extraction. 
(#5535)
6cc17217f4 is described below

commit 6cc17217f45211bb079ccbb32e2a9eb0bab56dab
Author: Svatopluk Dedic <[email protected]>
AuthorDate: Mon Mar 27 09:22:20 2023 -0700

    Fixed key escaping; fixed list/map property extraction. (#5535)
    
    Fixed key escaping; fixed list/map property extraction.
---
 .../gradle/tooling/NbProjectInfoBuilder.java       | 257 +++++++++++++--------
 .../modules/gradle/api/BuildPropertiesSupport.java |  11 +-
 .../loaders/ExtensionPropertiesExtractor.java      |  10 +-
 .../unit/data/buildprops/micronaut/build.gradle    |  15 ++
 .../loaders/ExtensionPropertiesExtractorTest.java  |  75 +++++-
 5 files changed, 267 insertions(+), 101 deletions(-)

diff --git 
a/extide/gradle/netbeans-gradle-tooling/src/main/java/org/netbeans/modules/gradle/tooling/NbProjectInfoBuilder.java
 
b/extide/gradle/netbeans-gradle-tooling/src/main/java/org/netbeans/modules/gradle/tooling/NbProjectInfoBuilder.java
index 193f4a3cee..bbf2118203 100644
--- 
a/extide/gradle/netbeans-gradle-tooling/src/main/java/org/netbeans/modules/gradle/tooling/NbProjectInfoBuilder.java
+++ 
b/extide/gradle/netbeans-gradle-tooling/src/main/java/org/netbeans/modules/gradle/tooling/NbProjectInfoBuilder.java
@@ -91,6 +91,7 @@ import org.gradle.api.logging.Logging;
 import org.gradle.api.plugins.ExtensionAware;
 import org.gradle.api.plugins.ExtensionContainer;
 import org.gradle.api.plugins.ExtensionsSchema.ExtensionSchema;
+import org.gradle.api.plugins.ExtraPropertiesExtension;
 import org.gradle.api.provider.Provider;
 import org.gradle.api.reflect.HasPublicType;
 import org.gradle.api.reflect.TypeOf;
@@ -100,6 +101,7 @@ import org.gradle.api.tasks.SourceSetContainer;
 import org.gradle.api.tasks.TaskDependency;
 import org.gradle.api.tasks.bundling.Jar;
 import org.gradle.api.tasks.testing.Test;
+import org.gradle.internal.extensibility.DefaultExtraPropertiesExtension;
 import org.gradle.jvm.JvmLibrary;
 import org.gradle.language.base.artifact.SourcesArtifact;
 import org.gradle.language.java.artifact.JavadocArtifact;
@@ -121,6 +123,11 @@ class NbProjectInfoBuilder {
      * project loader is enabled to FINER level.
      */
     private static final Logger LOG =  
Logging.getLogger(NbProjectInfoBuilder.class);
+
+    /**
+     * Name of the default extensibility point for various domain objects 
defined by Gradle.
+     */
+    private static final String DEFAULT_EXTENSION_NAME = "ext"; // NOI18N
     
     private static final String NB_PREFIX = "netbeans.";
     private static final Set<String> CONFIG_EXCLUDES = new HashSet<>(asList( 
new String[]{
@@ -536,32 +543,45 @@ class NbProjectInfoBuilder {
         return adapter.isMutableType(potentialValue);
     }
     
+    private void addNestedKeys(String prefix, Map<String, String> 
propertyTypes, Collection<String> keys) {
+            propertyTypes.merge(prefix + COLLECTION_KEYS_MARKER, 
String.join(";;", keys), (old, add) -> {
+                List<String> oldList = new 
ArrayList<>(Arrays.asList(old.split(";;")));
+                List<String> newList = Arrays.asList(add.split(";;"));
+                oldList.addAll(newList);
+                return String.join(";;", oldList);
+            });
+    }
+    
     private void inspectObjectAndValues0(Class clazz, Object object, String 
prefix, Map<String, Map<String, String>> globalTypes, Map<String, String> 
propertyTypes, Map<String, Object> defaultValues, Set<String> excludes, boolean 
type) {
         Class nonDecorated = findNonDecoratedClass(clazz);
         
         // record object's type first, even though the value may be excluded 
(i.e. ignored class). Do not add types for collection or map items -- to much 
clutter.
+        String typeKey = prefix;
+        if (prefix.endsWith(".")) {
+            typeKey = prefix.substring(0, prefix.length() - 1);
+        } else {
+            typeKey = prefix;
+        }
         if (type) {
-            String typeKey = prefix;
-            if (prefix.endsWith(".")) {
-                typeKey = prefix.substring(0, prefix.length() - 1);
-            } else {
-                typeKey = prefix;
-            }
             if (propertyTypes.putIfAbsent(typeKey, nonDecorated.getName()) != 
null && object == null) {
                 // type already introspected, no value to fetch properties 
from.
                 return;
             }
         }
-        if (clazz == null || (excludes == null && 
ignoreClassesPattern.matcher(clazz.getName()).matches())) {
+        
+        if (clazz == null || clazz.isEnum()) {
             return;
         }
-        if (clazz.isEnum() || clazz.isArray()) {
+        if (clazz.isArray() || (excludes == null && 
ignoreClassesPattern.matcher(clazz.getName()).matches())) {
+            // try to dump as a list/map
+            dumpValue(object, typeKey, propertyTypes, defaultValues, clazz, 
null);
             return;
         }
 
         MetaClass mclazz = 
GroovySystem.getMetaClassRegistry().getMetaClass(clazz);
         Map<String, String> globTypes = 
globalTypes.computeIfAbsent(nonDecorated.getName(), cn -> new HashMap<>());
         List<MetaProperty> props = mclazz.getProperties();
+        List<String> addedKeys = new ArrayList<>();
         for (MetaProperty mp : props) {
             Class propertyDeclaringClass = null;
             String getterName = null;
@@ -656,6 +676,8 @@ class NbProjectInfoBuilder {
                 }
             }
             
+            addedKeys.add(propName);
+            
             String cn = findNonDecoratedClass(t).getName();
             globTypes.put(propName, cn);
             propertyTypes.put(prefix + propName, cn);
@@ -675,6 +697,7 @@ class NbProjectInfoBuilder {
                         itemClass = 
findIterableItemClass(pubType.getConcreteClass());
                     }
                     propertyTypes.put(prefix + propName + 
COLLECTION_TYPE_MARKER, COLLECTION_TYPE_NAMED);
+                    propertyTypes.put(prefix + propName, 
findNonDecoratedClass(t).getName());
                     if (itemClass != null) {
                         propertyTypes.put(prefix + propName + 
COLLECTION_ITEM_MARKER, itemClass.getName());
                         newPrefix = prefix + propName + 
COLLECTION_ITEM_PREFIX; // NOI18N
@@ -683,88 +706,10 @@ class NbProjectInfoBuilder {
 
                     NamedDomainObjectContainer nc = 
(NamedDomainObjectContainer)value;
                     Map<String, ?> m = new HashMap<>(nc.getAsMap());
-                    List<String> ss = new ArrayList<>(m.keySet());
-                    propertyTypes.put(prefix + propName + 
COLLECTION_KEYS_MARKER, String.join(";;", ss));
-                    for (Map.Entry<String, ?> it : m.entrySet()) {
-                        String k = it.getKey();
-                        newPrefix = prefix + propName + "." + k + "."; // 
NOI18N
-                        Object v = it.getValue();
-                        defaultValues.put(prefix + propName + "." + k, 
Objects.toString(v)); // NOI18N
-                        inspectObjectAndValues(v.getClass(), v, newPrefix, 
globalTypes, propertyTypes, defaultValues, null, false);
-                    }
+                    dumpContainerProperties(m, prefix + propName, 
defaultValues);
                     dumped = true;
-                } else if (Iterable.class.isAssignableFrom(t)) {
-                    itemClass = findIterableItemClass(t);
-                    if (itemClass == null && typeParameters != null && 
!typeParameters.isEmpty()) {
-                        if (typeParameters.get(0) instanceof Class) {
-                            itemClass = (Class)typeParameters.get(0);
-                        }
-                    }
-                    
-                    propertyTypes.put(prefix + propName + 
COLLECTION_TYPE_MARKER, COLLECTION_TYPE_LIST);
-                    if (itemClass != null) {
-                        cn = findNonDecoratedClass(itemClass).getName();
-                        propertyTypes.put(prefix + propName + 
COLLECTION_ITEM_MARKER, cn);
-                        String newPrefix = prefix + propName + 
COLLECTION_ITEM_PREFIX; // NOI18N
-                        if (!cn.startsWith("java.lang.") && 
!Provider.class.isAssignableFrom(t)) { //NOI18N
-                            inspectObjectAndValues(itemClass, null, newPrefix, 
globalTypes, propertyTypes, defaultValues);
-                        }
-                    }
-                    
-                    if (value instanceof Iterable) {
-                        int index = 0;
-                        try {
-                            for (Object o : (Iterable)value) {
-                                String newPrefix = prefix + propName + "[" + 
index + "]."; // NOI18N
-                                defaultValues.put(prefix + propName + "[" + 
index + "]", Objects.toString(o)); //NOI18N
-                                inspectObjectAndValues(o.getClass(), o, 
newPrefix, globalTypes, propertyTypes, defaultValues, null, false);
-                                index++;
-                            }
-                        } catch (RuntimeException ex) {
-                            // values cannot be obtained
-                        }
-                        dumped = true;
-                    }
-                } else if (value instanceof Map) {
-                    Map mvalue = (Map)value;
-                    Set<Object> ks = mvalue.keySet();
-                    Class keyClass = findIterableItemClass(ks.getClass());
-                    if (keyClass == null || keyClass == 
java.lang.Object.class) {
-                        boolean ok = true;
-                        for (Object k : ks) {
-                            if (!(k instanceof String)) {
-                                ok = false;
-                            }
-                        }
-                        if (ok) {
-                            keyClass = String.class;
-                        }
-                    }
-                    if (keyClass == String.class) {
-                        itemClass = 
findIterableItemClass(mvalue.values().getClass());
-
-                        String keys = ks.stream().map(k -> 
k.toString()).map((String k) -> k.replace(";", 
"\\;")).collect(Collectors.joining(";;"));
-                        propertyTypes.put(prefix + propName + 
COLLECTION_KEYS_MARKER, keys);
-                        
-                        propertyTypes.put(prefix + propName + 
COLLECTION_TYPE_MARKER, COLLECTION_TYPE_MAP);
-                        if (itemClass != null) {
-                            cn = findNonDecoratedClass(itemClass).getName();
-                            propertyTypes.put(prefix + propName + 
COLLECTION_ITEM_MARKER, cn);
-                            String newPrefix = prefix + propName + 
COLLECTION_ITEM_PREFIX; // NOI18N
-                            if (!cn.startsWith("java.lang.") && 
!Provider.class.isAssignableFrom(t)) { //NOI18N
-                                inspectObjectAndValues(itemClass, null, 
newPrefix, globalTypes, propertyTypes, defaultValues);
-                            }
-                        }
-
-                        for (Object o : ks) {
-                            String k = o.toString();
-                            String newPrefix = prefix + propName + "[" + k + 
"]"; // NOI18N
-                            Object v = mvalue.get(o);
-                            defaultValues.put(newPrefix, Objects.toString(v)); 
// NOI18N
-                            inspectObjectAndValues(v.getClass(), v, newPrefix 
+ ".", globalTypes, propertyTypes, defaultValues, null, itemClass == null);
-                        }
-                        dumped = true;
-                    }
+                } else {
+                    dumped = dumpValue(value, prefix + propName, 
propertyTypes, defaultValues, t, typeParameters);
                 }
                 
                 if (!dumped) {
@@ -777,6 +722,129 @@ class NbProjectInfoBuilder {
                 }
             }
         }
+        addNestedKeys(typeKey, propertyTypes, addedKeys);
+    }
+    
+    private void dumpContainerProperties(Map<String, ?> m, String prefix, 
Map<String, Object> defaultValues) {
+        // merge with other properties
+        addNestedKeys(prefix, propertyTypes, m.keySet());
+
+        for (Map.Entry<String, ?> it : m.entrySet()) {
+            String k = it.getKey();
+            String newPrefix = prefix + "." + k + "."; // NOI18N
+            Object v = it.getValue();
+            defaultValues.put(prefix + "." + k, Objects.toString(v)); // NOI18N
+            inspectObjectAndValues(v.getClass(), v, newPrefix, globalTypes, 
propertyTypes, defaultValues, null, false);
+        }
+    }
+    
+    private boolean dumpValue(Object value, String prefix, Map<String, String> 
propertyTypes, Map<String, Object> defaultValues, Class t, List<Type> 
typeParameters) {
+        // attemtp to enumerate membrs of a Container or an Iterable.
+        Class itemClass = null;
+        String cn = null;
+        boolean dumped = false;
+        if ((value instanceof NamedDomainObjectContainer) && (value instanceof 
HasPublicType)) {
+            String newPrefix;
+
+            TypeOf pubType = ((HasPublicType)value).getPublicType();
+            if (pubType != null && pubType.getComponentType() != null) {
+                itemClass = pubType.getComponentType().getConcreteClass();
+            } else {
+                itemClass = findIterableItemClass(pubType.getConcreteClass());
+            }
+            propertyTypes.put(prefix + COLLECTION_TYPE_MARKER, 
COLLECTION_TYPE_NAMED);
+            if (itemClass != null) {
+                propertyTypes.put(prefix + COLLECTION_ITEM_MARKER, 
itemClass.getName());
+                newPrefix = prefix + COLLECTION_ITEM_PREFIX; // NOI18N
+                inspectObjectAndValues(itemClass, null, newPrefix, 
globalTypes, propertyTypes, defaultValues);
+            }
+
+            NamedDomainObjectContainer nc = (NamedDomainObjectContainer)value;
+            Map<String, ?> m = new HashMap<>(nc.getAsMap());
+            List<String> ss = new ArrayList<>(m.keySet());
+            propertyTypes.put(prefix + COLLECTION_KEYS_MARKER, 
String.join(";;", ss));
+            for (String k : m.keySet()) {
+                newPrefix = prefix + "." + k + "."; // NOI18N
+                Object v = m.get(k);
+                defaultValues.put(prefix + "." + k, Objects.toString(v)); // 
NOI18N
+                inspectObjectAndValues(v.getClass(), v, newPrefix, 
globalTypes, propertyTypes, defaultValues, null, false);
+            }
+            dumped = true;
+        } else if (Iterable.class.isAssignableFrom(t)) {
+            itemClass = findIterableItemClass(t);
+            if (itemClass == null && typeParameters != null && 
!typeParameters.isEmpty()) {
+                if (typeParameters.get(0) instanceof Class) {
+                    itemClass = (Class)typeParameters.get(0);
+                }
+            }
+
+            propertyTypes.put(prefix + COLLECTION_TYPE_MARKER, 
COLLECTION_TYPE_LIST);
+            
+            if (itemClass != null) {
+                cn = findNonDecoratedClass(itemClass).getName();
+                propertyTypes.put(prefix + COLLECTION_ITEM_MARKER, cn);
+                String newPrefix = prefix + COLLECTION_ITEM_PREFIX; // NOI18N
+                if (!cn.startsWith("java.lang.") && 
!Provider.class.isAssignableFrom(t)) { //NOI18N
+                    inspectObjectAndValues(itemClass, null, newPrefix, 
globalTypes, propertyTypes, defaultValues);
+                }
+            }
+
+            if (value instanceof Iterable) {
+                int index = 0;
+                try {
+                    for (Object o : (Iterable)value) {
+                        String newPrefix = prefix + "[" + index + "]."; // 
NOI18N
+                        defaultValues.put(prefix + "[" + index + "]", 
Objects.toString(o)); //NOI18N
+                        inspectObjectAndValues(o.getClass(), o, newPrefix, 
globalTypes, propertyTypes, defaultValues, null, false);
+                        index++;
+                    }
+                } catch (RuntimeException ex) {
+                    // values cannot be obtained
+                }
+                dumped = true;
+            }
+        } else if (value instanceof Map) {
+            Map mvalue = (Map)value;
+            Set<Object> ks = mvalue.keySet();
+            Class keyClass = findIterableItemClass(ks.getClass());
+            if (keyClass == null || keyClass == java.lang.Object.class) {
+                boolean ok = true;
+                for (Object k : ks) {
+                    if (!(k instanceof String)) {
+                        ok = false;
+                    }
+                }
+                if (ok) {
+                    keyClass = String.class;
+                }
+            }
+            if (keyClass == String.class) {
+                itemClass = findIterableItemClass(mvalue.values().getClass());
+
+                String keys = ks.stream().map(k -> k.toString()).map((String 
k) -> k.replace(";", "\\;")).collect(Collectors.joining(";;"));
+                propertyTypes.put(prefix + COLLECTION_KEYS_MARKER, keys);
+
+                propertyTypes.put(prefix + COLLECTION_TYPE_MARKER, 
COLLECTION_TYPE_MAP);
+                if (itemClass != null) {
+                    cn = findNonDecoratedClass(itemClass).getName();
+                    propertyTypes.put(prefix + COLLECTION_ITEM_MARKER, cn);
+                    String newPrefix = prefix + COLLECTION_ITEM_PREFIX; // 
NOI18N
+                    if (!cn.startsWith("java.lang.") && 
!Provider.class.isAssignableFrom(t)) { //NOI18N
+                        inspectObjectAndValues(itemClass, null, newPrefix, 
globalTypes, propertyTypes, defaultValues);
+                    }
+                }
+
+                for (Object o : ks) {
+                    String k = o.toString();
+                    String newPrefix = prefix + "[" + k + "]"; // NOI18N
+                    Object v = mvalue.get(o);
+                    defaultValues.put(newPrefix, Objects.toString(v)); // 
NOI18N
+                    inspectObjectAndValues(v.getClass(), v, newPrefix + ".", 
globalTypes, propertyTypes, defaultValues, null, itemClass == null);
+                }
+                dumped = true;
+            }
+        }
+        return dumped;
     }
     
     private static Class findNonDecoratedClass(Class clazz) {
@@ -810,7 +878,7 @@ class NbProjectInfoBuilder {
             
             Object ext;
             try {
-                ext = project.getExtensions().getByName(extName);
+                ext = container.getByName(extName);
                 if (ext == null) {
                     continue;
                 }
@@ -818,6 +886,15 @@ class NbProjectInfoBuilder {
                 // ignore, the extension could not be obtained, ignore.
                 continue;
             }
+            
+            // special case for 'ext' DefaultProperiesExtension whose 
properties are 'merged' with the base object
+            // can be read in the buildscript as if the object itself defined 
them
+            if (DEFAULT_EXTENSION_NAME.equals(extName) && (ext instanceof 
ExtraPropertiesExtension)) {
+                String p = prefix.endsWith(".") ? prefix.substring(0, 
prefix.length() - 1) : prefix;
+                
dumpContainerProperties(((ExtraPropertiesExtension)ext).getProperties(), p, 
values);
+                continue;
+            }
+            
             Class c = findNonDecoratedClass(ext.getClass());
             propertyTypes.put(prefix + extName, c.getName());
             inspectObjectAndValues(ext.getClass(), ext, prefix + extName + 
".", globalTypes, propertyTypes, values);
diff --git 
a/extide/gradle/src/org/netbeans/modules/gradle/api/BuildPropertiesSupport.java 
b/extide/gradle/src/org/netbeans/modules/gradle/api/BuildPropertiesSupport.java
index 091992e9b1..7d247f5dc0 100644
--- 
a/extide/gradle/src/org/netbeans/modules/gradle/api/BuildPropertiesSupport.java
+++ 
b/extide/gradle/src/org/netbeans/modules/gradle/api/BuildPropertiesSupport.java
@@ -180,10 +180,12 @@ public final class BuildPropertiesSupport {
     }
     
     /**
-     * Returns keys of map-style properties. Works only for properties of 
{@link PropertyKind#MAP}.
-     * @param owner
-     * @return 
+     * Returns keys of map-style properties. Works only for properties of 
{@link PropertyKind#MAP} or
+     * {@link PropertyKind#STRUCTURE}. May return an empty list, if keys 
cannot be enumerated or represented as Strings.
+     * @param owner the property
+     * @return list of keys, possibly empty. Does not return null
      */
+    @NonNull
     public Collection<String> keys(Property owner) {
         if ((owner.getKind() != PropertyKind.STRUCTURE) && (owner.getKind() != 
PropertyKind.MAP)) {
             return Collections.emptyList();
@@ -204,8 +206,9 @@ public final class BuildPropertiesSupport {
      * @param base the map property
      * @param key map item's key
      * @param path optional path within an item to the property.
-     * @return map item, or a property of a map item.
+     * @return map item, or a property of a map item. Null, if the item can 
not be found.
      */
+    @CheckForNull
     public Property get(Property base, String key, String path) {
         if ((base.getKind() != PropertyKind.MAP)) {
             return null;
diff --git 
a/extide/gradle/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractor.java
 
b/extide/gradle/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractor.java
index 1f45a2b046..10c3ebe9fe 100644
--- 
a/extide/gradle/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractor.java
+++ 
b/extide/gradle/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractor.java
@@ -27,6 +27,7 @@ import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.netbeans.modules.gradle.api.BuildPropertiesSupport;
 import org.netbeans.modules.gradle.spi.GradleFiles;
 import org.netbeans.modules.gradle.spi.ProjectInfoExtractor;
@@ -121,15 +122,16 @@ public class ExtensionPropertiesExtractor implements 
ProjectInfoExtractor {
                 default:
                     return null;
             }
-            if (base.getName()== null || propertyPath == null) {
+            if (base.getName()== null) {
                 return null;
             }
             Object id = base.getId();
             String path;
+            String suffix = propertyPath == null ? "" : "." + propertyPath; // 
NOI18N
             if (id == null) {
-                path = base.getName() + "." + propertyPath; // NOI18N
+                path = base.getName() + suffix; // NOI18N
             } else if (id instanceof String) {
-                path = id.toString() + "." + propertyPath; // NOI18N
+                path = id.toString() + suffix; // NOI18N
             } else {
                 return null;
             }
@@ -170,7 +172,7 @@ public class ExtensionPropertiesExtractor implements 
ProjectInfoExtractor {
             if (c == null) {
                 return null;
             }
-            return Arrays.asList(c.split(";;")).stream().map(s -> 
s.replaceAll("\\;", ";")).collect(Collectors.toList());
+            return Stream.of(c.split(";;")).map(s -> s.replace("\\;", 
";")).collect(Collectors.toList());
         }
 
         @Override
diff --git a/extide/gradle/test/unit/data/buildprops/micronaut/build.gradle 
b/extide/gradle/test/unit/data/buildprops/micronaut/build.gradle
index 15ddebdf6a..9e0b09a314 100644
--- a/extide/gradle/test/unit/data/buildprops/micronaut/build.gradle
+++ b/extide/gradle/test/unit/data/buildprops/micronaut/build.gradle
@@ -61,7 +61,22 @@ micronaut {
 
 graalvmNative.binaries.main.systemProperties = [prop1 : 'value1', 'prop2': 
'value2', 'prop;;3': 'value3' ];
 
+graalvmNative.binaries.main.buildArgs.addAll([ 'x', 'y', 'z' ])
+
+// define an extra property using extension mechanism
+graalvmNative.ext.weirdKeys = [ 
+    normalKey: 'Hello!',
+    'semi;key': "There",
+    'semi;;key': "DoubleSemi",
+    'semi;\\;key': "EscapedSemi"
+]
+
+// initialize a List<String>
+tasks.named('nativeCompile')  {
+    options.get().getRuntimeArgs().addAll(['a', 'b'])
+}
 
 println project.group
 println project.name
 println project.version
+println tasks.nativeCompile.options.get().getRuntimeArgs().get()
diff --git 
a/extide/gradle/test/unit/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractorTest.java
 
b/extide/gradle/test/unit/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractorTest.java
index 2f766babcc..372f3038c2 100644
--- 
a/extide/gradle/test/unit/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractorTest.java
+++ 
b/extide/gradle/test/unit/src/org/netbeans/modules/gradle/loaders/ExtensionPropertiesExtractorTest.java
@@ -20,15 +20,22 @@ package org.netbeans.modules.gradle.loaders;
 
 import java.io.File;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
 import static junit.framework.TestCase.assertNotNull;
+import org.gradle.internal.impldep.com.google.common.collect.Streams;
 import org.netbeans.api.project.Project;
 import org.netbeans.api.project.ProjectManager;
 import org.netbeans.api.project.ui.OpenProjects;
 import org.netbeans.junit.NbTestCase;
 import org.netbeans.modules.gradle.ProjectTrust;
 import org.netbeans.modules.gradle.api.BuildPropertiesSupport;
+import org.netbeans.modules.gradle.api.BuildPropertiesSupport.PropertyKind;
 import org.netbeans.modules.gradle.api.NbGradleProject;
 import org.netbeans.modules.gradle.options.GradleExperimentalSettings;
 import org.openide.filesystems.FileObject;
@@ -164,6 +171,25 @@ public class ExtensionPropertiesExtractorTest extends 
NbTestCase {
         item = support.get(prop, "test", null);
         assertNotNull(item);
     }
+    
+    public void testAddedListExtensionProperty() throws Exception {
+        Project p = makeProject("buildprops/micronaut");
+        BuildPropertiesSupport support = BuildPropertiesSupport.get(p);
+        assertNotNull(support);
+        
+        BuildPropertiesSupport.Property prop;
+        
+
+        prop = support.findExtensionProperty("graalvmNative", 
"binaries.main.buildArgs");
+        assertEquals(BuildPropertiesSupport.PropertyKind.LIST, prop.getKind());
+        Iterable<BuildPropertiesSupport.Property> it = support.items(prop, 
null);
+        assertNotNull(it);
+        Iterator<BuildPropertiesSupport.Property> iter = it.iterator();
+        assertTrue(iter.hasNext());
+        
+        List<String> l = 
Streams.stream(iter).map(BuildPropertiesSupport.Property::getStringValue).collect(Collectors.toList());
+        assertEquals(Arrays.asList("x", "y", "z"), l);
+    }
 
     public void testMapExtensionProperty2() throws Exception {
         Project p = makeProject("buildprops/micronaut");
@@ -194,7 +220,33 @@ public class ExtensionPropertiesExtractorTest extends 
NbTestCase {
         assertNotNull(item);
         assertEquals("value3", item.getStringValue());
     }
-
+    
+    /**
+     * Keys are ;; delimited, check various weird keys that needs to be 
encoded, if they decode back properly.
+     * @throws Exception 
+     */
+    public void testWeirdKeysMapExtensionProperty() throws Exception {
+        Project p = makeProject("buildprops/micronaut");
+        BuildPropertiesSupport support = BuildPropertiesSupport.get(p);
+        assertNotNull(support);
+        
+        BuildPropertiesSupport.Property prop;
+        prop = support.findExtensionProperty("graalvmNative", "weirdKeys");
+        prop = support.get(prop, "main", null);
+        prop = support.findExtensionProperty("graalvmNative", null);
+        BuildPropertiesSupport.Property prop2 = support.get(prop, "binaries", 
null);
+        prop = support.findExtensionProperty("graalvmNative", "weirdKeys");
+        
+        
+        Collection<String> keys = support.keys(prop);
+        assertNotNull(keys);
+        
+        List<String> sorted = new ArrayList<>(keys);
+        Collections.sort(sorted);
+        
+        assertEquals(Arrays.asList("normalKey", "semi;;key", "semi;\\;key", 
"semi;key"), sorted);
+    }
+    
 
     public void testSimpleTaskProperty() throws Exception {
         Project p = makeProject("buildprops/micronaut");
@@ -213,8 +265,8 @@ public class ExtensionPropertiesExtractorTest extends 
NbTestCase {
         prop = support.findTaskProperty("nativeCompile", "options");
         assertNotNull(prop);
         assertEquals(BuildPropertiesSupport.PropertyKind.STRUCTURE, 
prop.getKind());
-
-        assertTrue(support.keys(prop).isEmpty());
+        
+        assertFalse(support.keys(prop).isEmpty());
         assertFalse(support.items(prop, null).iterator().hasNext());
 
         prop = support.findTaskProperty("nativeTestCompile", 
"workingDirectory");
@@ -228,4 +280,21 @@ public class ExtensionPropertiesExtractorTest extends 
NbTestCase {
         assertFalse(support.items(prop, null).iterator().hasNext());
     }
     
+    /**
+     * Checks that a list property of a task is populated
+     * @throws Exception 
+     */
+    public void testTaskListProperty() throws Exception {
+        Project p = makeProject("buildprops/micronaut");
+        BuildPropertiesSupport support = BuildPropertiesSupport.get(p);
+        assertNotNull(support);
+        
+        BuildPropertiesSupport.Property prop = 
support.findTaskProperty("nativeCompile", "options.runtimeArgs");
+        assertNotNull(prop);
+        assertEquals(PropertyKind.LIST, prop.getKind());
+        
+        assertTrue(support.keys(prop).isEmpty());
+        assertTrue(support.items(prop, null).iterator().hasNext());
+    }
+    
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to