Migration to Unity 5.6.1: APIUpdater

Hi,

I’m migrating from Unity 5.5.3 to 5.6.1. Building for Android (il2cpp) fails with following errors:

Exception: C:\Program Files\Unity-5.6.1p\Editor\Data\Tools/UnusedByteCodeStripper2/UnusedBytecodeStripper2.exe did not run properly!
UnityEditorInternal.Runner.RunManagedProgram (System.String exe, System.String args, System.String workingDirectory, UnityEditor.Scripting.Compilers.CompilerOutputParserBase parser, System.Action`1 setupStartInfo) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/BuildUtils.cs:98)
UnityEditorInternal.AssemblyStripper.RunAssemblyLinker (IEnumerable`1 args, System.String& out, System.String& err, System.String linkerPath, System.String workingDirectory) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyStripper.cs:102)
UnityEditorInternal.AssemblyStripper.StripAssembliesTo (System.String[] assemblies, System.String[] searchDirs, System.String outputFolder, System.String workingDirectory, System.String& output, System.String& error, System.String linkerPath, IIl2CppPlatformProvider platformProvider, IEnumerable`1 additionalBlacklist) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyStripper.cs:95)
...
UnityEditor.PostprocessBuildPlayer.Postprocess (BuildTargetGroup targetGroup, BuildTarget target, System.String installPath, System.String companyName, System.String productName, Int32 width, Int32 height, System.String downloadWebplayerUrl, System.String manualDownloadWebplayerUrl, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.BuildReporting.BuildReport report) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs:186)
UnityEditor.HostView:OnGUI()

and

APIUpdater encountered some issues and was not able to finish.
	System.InvalidOperationException: Sequence contains more than one element
	  at System.Linq.Enumerable.SingleOrDefault[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x000a3] in <776c86d7978548379a28dce0f5e4ccbb>:0 
	  at CSharpUpdater.Steps.MemberReferenceReplacerBase`1[T].CommentedOutClashingNamedExpression (Microsoft.CodeAnalysis.CSharp.Syntax.SimpleNameSyntax namedExpression, System.String replacement) [0x0001a] in <b7cb13f7ec2246c886e193d293370e2c>:0
      ...
	  at ScriptUpdater.Program.UpdateLanguage (APIUpdater.Framework.Core.IScriptUpdater updater, APIUpdater.Framework.Configuration.CompilerResponseFile responseFile, System.String unityDataPath, System.String outputPath) [0x000b3] in <a7ef413534cd40558c8276304ebb3af4>:0 
	  at ScriptUpdater.Program.Main (System.String[] args) [0x000d5] in <a7ef413534cd40558c8276304ebb3af4>:0

I’ve already filed tickets 903332 and 902973 some time ago.

Could you please check call to SingleOrDefault() somewhere in CommentedOutClashingNamedExpression() or neighbourhood?

Thanks!

@JoshPeterson

@JoshPeterson …Or just open sources of “API Updater” so I could fix it by myself and pull-request.

Hi @Qbit86

Regarding the Updater, are you willing to run a modified version of it? If so, I can change it to log only the expression (code) that is causing the crash.

Best

Adriano

Yes, I could try modified version with enhanced logging.

According to dotPeek, the problem is in this method:

    private bool CommentedOutClashingNamedExpression(SimpleNameSyntax namedExpression, string replacement)
    {
      if (namedExpression == null)
        return false;
      InitializerExpressionSyntax expressionSyntax = namedExpression.Ancestors(true).OfType<InitializerExpressionSyntax>().SingleOrDefault<InitializerExpressionSyntax>();
      if (expressionSyntax == null)
        return false;
      SourceRange objectInitializer = this.RangeToCommentOutDueToClashingNameInObjectInitializer(expressionSyntax.Expressions.OfType<AssignmentExpressionSyntax>(), namedExpression, replacement);
      if (!objectInitializer.IsValid)
        return false;
      this.UpdateCollector.Insert(objectInitializer.Start, "/*", (object) null, (object) null);
      this.UpdateCollector.Insert(objectInitializer.End, "*/", (object) null, (object) null);
      this.UpdaterContext.Listener.Log(APIUpdater.Framework.Log.LogLevel.Warning, "warning: Expression '{0}' in '{1}' has been commented out due to member '{2}' being replaced with '{3}'.", (object) namedExpression, (object) namedExpression.GetLocation().GetMappedLineSpan().Path, (object) namedExpression.Identifier, (object) replacement);
      return true;
    }

Looks like wrong assumption on amount of InitializerExpressionSyntax nodes. Maybe it’s worth trying to replace SingleOrDefault<InitializerExpressionSyntax>() call with iteration over all nodes? foreach (InitializerExpressionSyntax expressionSyntax in namedExpression.Ancestors(true).OfType<InitializerExpressionSyntax>()) { ... }

can you send me an email so I can send you a link to download the modified version ? (adriano@unity3d.com)

Thanks, I’ve received zip-archive! I will try it tomorrow at work (located in UTC+3 time zone).